0
点赞
收藏
分享

微信扫一扫

第九届蓝桥杯Java组省赛

余寿 2022-04-07 阅读 44

A. 第几天

题目描述:

思路解析:

代码:

package9;

/**
 * @author: DreamCode
 * @file: A_第几天.java
 * @time: 2022年3月21日-下午9:54:37
 * @答案:125
 */
public class A_第几天 {

	static int[] arr= {31,29,31,30,31,30,31,31,30,31,30,31};
	public static void main(String[] args) {
		int ans = 0;
		for(int i=0;i<4;i++) {  //前4个月的天数
			ans+=arr[i];
		}
		ans+=4;
		System.out.println(ans);
	}

}

B. 方格计数

题目描述:

思路解析:

代码:

package9;

/**
 * @author: DreamCode
 * @file: B_方格计数.java
 * @time: 2022年3月21日-下午9:58:38
 * @答案: 3137548
 */
public class B_方格计数 {

	public static void main(String[] args) {
		int res=0;
		int r=1000;
		for(int x=1;x<=1000;x++) {
			for(int y=1;y<=1000;y++) {
				if(distance(x,y)<=r) {
					res++;
				}
			}
		}
		System.out.println(res*4);

	}

	private static double distance(int x, int y) {
		double d=Math.sqrt(x*x+y*y);
		return d;
	}

}

C. 复数幂

题目描述:

思路解析:

代码:

package9;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigInteger;

/**
 * @author: DreamCode
 * @file: B_方格计数.java
 * @time: 2022年3月21日-下午9:58:38
 */
public class C_复数幂 {

	public static void main(String[] args) throws IOException {
		BigInteger a = new BigInteger("2");
		BigInteger b = new BigInteger("3");
		for (int i = 0; i < 123455; i++) {
			BigInteger c = a;
			BigInteger d = b;
			a = (new BigInteger("2").multiply(c)).subtract(new BigInteger("3").multiply(d));
			b = (new BigInteger("2").multiply(d)).add(new BigInteger("3").multiply(c));
		}
		System.setOut(new PrintStream(new File("src/第9届/C_OutPut.txt")));
		System.out.print(a);
		if (b.compareTo(BigInteger.ZERO) > 0) {
			System.out.print('+');
		}
		System.out.print(b);
		System.out.print("i");
	}
}

D. 测试次数

题目描述:

思路解析:

代码:

package9;

/**
 * @author: DreamCode
 * @file: D_测试次数.java
 * @time: 2022年3月21日-下午11:04:09 @答案:19
 */
public class D_测试次数 {

	public static void main(String[] args) {
		int n = 1000;
		int k = 3;
		int ans = DP(k, n);
		System.out.println(ans);
	}

	private static int DP(int k, int n) {
		int[][] dp = new int[k + 1][n + 1];
		for (int i = 1; i <= n; i++) {
			dp[1][i] = i; // 只有一部手机的时候,测试n层肯定是n次
		}
		for (int i = 2; i <= k; i++) { // 手机数从2-k
			for (int j = 1; j <= n; j++) { // 测试层数从1-n
				int strategy = Integer.MAX_VALUE; // 记录最佳策略结果
				for (int p = 1; p <= j; p++) { // 测试j层有i部手机,模拟分别从1-j层开始摔,找最坏运气,最佳策略结果
					int N = dp[i][j - p];// 当前层没摔坏,则需要用i部手机测试剩下的j-p层
					int Y = dp[i - 1][p - 1];// 当前层摔坏了,则需要用i-1部手机测试剩下的p-1层
					int bad_luck = 1 + Math.max(N, Y); // 最坏的运气
					strategy = Math.min(strategy, bad_luck);// 最佳丢手机策略
				}
				dp[i][j] = strategy;
			}
		}
		return dp[k][n];
	}

}

E. 快速排序

代码填空题

package9;

import java.util.Random;

/**
 * @author: DreamCode
 * @file: E_快速排序.java
 * @time: 2022年3月21日-下午11:05:26
 */
public class E_快速排序 {

	/**
	 * 以下代码可以从数组a[]中找出第k小的元素。
	 * 
	 * 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。
	 * 
	 * 请仔细阅读分析源码,填写划线部分缺失的内容。
	 */
	public static int quickSelect(int a[], int l, int r, int k) {
		Random rand = new Random();
		int p = rand.nextInt(r - l + 1) + l;
		int x = a[p];
		int tmp = a[p];
		a[p] = a[r];
		a[r] = tmp;
		int i = l, j = r;
		while (i < j) {
			while (i < j && a[i] < x)
				i++;
			if (i < j) {
				a[j] = a[i];
				j--;
			}
			while (i < j && a[j] > x)
				j--;
			if (i < j) {
				a[i] = a[j];
				i++;
			}
		}
		a[i] = x;
		p = i;
		if (i - l + 1 == k)
			return a[i];
		if (i - l + 1 < k)
			return quickSelect(a,i+1,r,k-i+1); // 填空
		else
			return quickSelect(a, l, i - 1, k);
	}

	public static void main(String args[]) {
		int[] a = { 1, 4, 2, 8, 5, 7 };
		System.out.println(quickSelect(a, 0, 5, 4));
	}
}

F. 递增三元组

题目描述:

思路解析:

package9;

import java.util.Arrays;
import java.util.Scanner;

public class F_递增三元组{

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int N=scanner.nextInt();
		int[] A=new int[N];
		int[] B=new int[N];
		int[] C=new int[N];
		for(int i=0;i<N;i++) {
			A[i]=scanner.nextInt();			
		}
		for(int i=0;i<N;i++) {
			B[i]=scanner.nextInt();	
		}
		for(int i=0;i<N;i++) {
			C[i]=scanner.nextInt();
		}
		Arrays.sort(A);
		Arrays.sort(B);
		Arrays.sort(C);
		long sum=0;
		int p=0;
		int q=0;
		for(int i=0;i<N;i++) {  
			while(p<N&&A[p]<B[i]) {
				p++;
			}
			while(q<N&&C[q]<=B[i]) {
				q++;
			}
			sum+=(long)(p)*(N-q);
		}
		System.out.println(sum);
	}
}

G. 螺旋折现

试题描述:

思路解析:

代码:

package9;

import java.util.Scanner;

/**
 * @author: DreamCode
 * @file: G_螺旋折线.java
 * @time: 2022年3月23日-下午8:16:00
 */
public class G_螺旋折线 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		long x = scanner.nextLong();
		long y = scanner.nextLong();
		long k = Math.max(Math.abs(x), Math.abs(y));
		long sum = (8 + 8 * k) * k / 2;
		long d = 0;// 计算与当前边长正方形左下角坐标的距离,并将sum减去距离值
		if (y == k) { // 上边界
			d = k - x + 4 * k;
		} else if (x == k) {// 右边界
			d = y - (-k) + 2 * k;
		} else if (y == -k) {// 下边界
			d = x - (-k);
		} else if (x == -k) {// 左边界
			d = k - y + 6 * k;
		}
		sum -= d;
		System.out.println(sum);
	}
}

H. 日志统计

题目描述:

思路解析:

代码:

package9;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author: DreamCode
 * @file: H_日志统计.java
 * @time: 2022年3月23日-下午8:56:03
 */
public class H_日志统计 {

	static class log {
		public int ts;
		public int td;

		public log(int ts, int td) {
			super();
			this.ts = ts;
			this.td = td;
		}
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int N = scanner.nextInt();
		int D = scanner.nextInt();
		int K = scanner.nextInt();
		log[] arr = new log[N];
		for (int i = 0; i < N; i++) {
			arr[i] = new log(scanner.nextInt(), scanner.nextInt());
		}
		Arrays.sort(arr, new Comparator<log>() {  //指定排序规则
			@Override
			public int compare(log o1, log o2) {
				if (o1.ts == o2.ts) {
					return o1.td < o2.td ? -1 : 1;
				}
				return o1.ts < o2.ts ? -1 : 1;
			}
		});
		solve(arr, D, K);
	}

	private static void solve(log[] arr, int D, int K) {
		// TODO 尺取法解决问题
		Map<Integer, Integer> rec = new HashMap<>(); // hash表记录每种id的点赞数
		Set<Integer> ans = new TreeSet<>(); // 记录热帖的td,默认从小到大排序且去重
		int p = 0, q = 0; // 尺取法的双指针
		while (q < arr.length) { // 遍历每一种情况
			while (arr[q].ts < arr[p].ts + D) {
				q++;
				if(q==arr.length) {
					break;
				}
			}
			for (int i = p; i < q; i++) { // 一次尺,尺子的长度满足[t,t+D);
				if (rec.get(arr[i].td) == null) {
					rec.put(arr[i].td, 1);
				} else {
					rec.put(arr[i].td, rec.get(arr[i].td) + 1);
				}
			}
			for (Map.Entry<Integer, Integer> entry : rec.entrySet()) { // 查询当前的尺满足热帖要求的id
				if (entry.getValue() >= K) {
					ans.add(entry.getKey());
				}
			}
			rec.clear(); //每一次尺取完以后将记录数组清空
			p++;
		}
		Iterator<Integer> iterator=ans.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
	}
}

I. 全球变暖

题目描述:

思路解析:

代码:

package9;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

/**
 * @author: DreamCode
 * @file: I_全球变暖.java
 * @time: 2022年3月24日-下午10:58:21
 */
public class I_全球变暖 {

	static class point {
		public int x;
		public int y;

		public point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

	}

	static int[] x_stride = { -1, 1, 0, 0 }; // 分别代表上下左右移动
	static int[] y_stride = { 0, 0, -1, 1 };
	static boolean[][] vis; // 记录地图上的该点是否已访问
	static char[][] map; // 记录地图上的元素
	static int ans = 0; // 记录最终会被淹没的岛屿数量
	static int n;

	public static void main(String[] args) {
		Scanner scanner = new Scanner(new BufferedInputStream(System.in));
		n = scanner.nextInt();
		map = new char[n][n];
		vis = new boolean[n][n];
		for (int i = 0; i < n; i++) {
			map[i] = scanner.next().toCharArray();
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (map[i][j] == '#' && !vis[i][j]) { // 当前点未访问且当前点未 # ,以该点为中心进行BFS判断是否连通
					BFS(i, j);
				}
			}
		}
		System.out.println(ans);
	}

	private static void BFS(int x, int y) {
		// TODO BFS遍历
		int cnt1 = 0; // 记录靠近海洋的陆地数量
		int cnt2 = 0; // 记录陆地的数量
		Queue<point> queue = new LinkedList<>(); // 构造队列存储每一个点
		queue.offer(new point(x, y));
		while (!queue.isEmpty()) {
			cnt2++;
			point p = queue.peek();
			queue.remove();
			vis[p.x][p.y] = true; // 标记该点已访问
			boolean flag = false; // 默认当前陆地点不靠近海洋
			for (int i = 0; i < 4; i++) {// 遍历四个方向
				int next_x = p.x + x_stride[i];
				int next_y = p.y + y_stride[i];
				if (next_x >= 0 && next_x < n && next_y >= 0 && next_y < n) { // 边界判断
					if (map[next_x][next_y] == '.') { // 当前的陆地点附近具有海洋,flag设为true
						flag = true;
					}
					if (map[next_x][next_y] == '#' && !vis[next_x][next_y]) {// 附近点具有未访问的陆地,加入队列
						queue.offer(new point(next_x, next_y));
					}
				}
			}
			if (flag) { // 当前的陆地点附近具有海洋
				cnt1++;
			}
		}
		if (cnt1 == cnt2) { // 当前岛屿的每一块陆地都靠海,会被淹没
			ans++;
		}
	}
}

J. 堆的计数

题目描述:

思路解析:

代码:

package9;

import java.util.Scanner;

/**
 * @author: DreamCode
 * @file: J_堆的计数.java
 * @time: 2022-4-7-22:41:26
 */

public class J_堆的计数 {
	private static final int MOD = 1000000009;  //质数
	private static int N;
	private static int[] size; // 记录每个节点的size
	private static long[] jie; // 记录1~N的阶乘
	private static long[] ni; // 记录1~N的阶乘的逆元

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		size = new int[N + 1];
		jie = new long[N + 1];
		ni = new long[N + 1];
		initSize();  //预处理每一个节点的左右子树节点的个数
		initJie();  //预处理阶层与数的逆元
		System.out.println(dp());
		sc.close();
	}

	private static long dp() {  //动态规划递推
		long[] d = new long[N + 1]; // d[i]表示的是i号节点作为根,小根堆的种数
		for (int x = N; x >= 1; x--) {
			if (2 * x + 1 <= N) {
				d[x] = c(size[x] - 1, size[2 * x]) * d[2 * x] % MOD * d[2 * x + 1] % MOD;
			} else if (2 * x <= N) {
				d[x] = c(size[x] - 1, size[2 * x]) * d[2 * x] % MOD;
			} else {
				d[x] = 1;
			}
		}
		return d[1];
	}

	private static void initJie() {  //预处理阶乘与模的逆元
		jie[0] = 1;
		ni[0] = 1;
		for (int i = 1; i <= N; i++) {
			jie[i] = jie[i - 1] * i % MOD;  //递推计算阶乘
			ni[i] = qpow(jie[i], MOD - 2);  //i的逆元为i!^(MOD-2)
		}
	}

	private static long qpow(long a, int n) {  //快速幂运算
		if (a == 0) {
			return 0;
		}
		long ans = 1;
		long x = a;
		while (n > 0) {
			if ((n & 1) == 1) {
				ans = ans * x % MOD;
			}
			n >>= 1;
			x = x * x % MOD;
		}
		return ans;
	}

	private static void initSize() {  //初始化每个节点左右子节点的数目。左节点的数目+右节点的数目+1
		for (int i = N; i >= 1; i--) {
			size[i] = (2 * i <= N ? size[2 * i] : 0) + (2 * i + 1 <= N ? size[2 * i + 1] : 0) + 1;
		}
	}

	private static long c(int n, int r) {  //求组合数:n!/r!/(n-r)!
		return jie[n] * ni[r] % MOD * ni[n - r] % MOD;
	}
}

举报

相关推荐

0 条评论