十五届蓝桥杯省赛Java B组(持续更新..)
目录
- 十五届蓝桥杯省赛Java B组
- 第一题:报数
- 第二题:类斐波那契数
- 第三题:分布式队列
- 第四题:食堂
- 第五题:最优分组
- 第六题:星际旅行
- 第七题:LITS游戏
- 第八题:拼十字
十五届蓝桥杯省赛Java B组
第一题:报数
📚
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);long result = 202420242024L / 2 * 24;//思想:奇数位都是20的倍数,偶数位都是24的倍数,可知202420242024的一半为奇数,第202420242024位除以2乘以24就能得到答案//举个例子:第4位是第2个24的倍数,第6位是第3个24的倍数......那第202420242024位就是第101210121012个24的倍数,//所以答案就是:202420242024 / 2 * 24System.out.println(result);scan.close();}
}
主要是找规律,硬解很难解出来。
第二题:类斐波那契数
因为是找最大,所以逆序遍历会快点,第一个符合条件的数就是答案。
我的暴力解法,比赛不会那只能放在一边让他跑了,按道理来说是能跑出来的。
package test;import javax.swing.*;
import java.util.*;public class Main {static int N = 10000000;static int[] a = new int[20];static long[] b = new long[N];public static void main(String[] args) {Scanner sc = new Scanner(System.in);for (int i = N; i >= 197; i--) {if(check(i)){System.out.println(i);break;}else {System.out.println(i);}}}// 检查是否是 类斐波那契 循环数static boolean check(int x) { // num是位数String str = x + "";int len = str.length();for (int i = 0; i < len; i++) {b[i + 1] = str.charAt(i) - '0';}for (int i = len + 1; b[i - 1] < x; i++) {b[i] = dfs(i);
// System.out.println(" i:"+i);
// System.out.println(b[i]);if( b[i] == x) return true;if( b[i] > x) return false;}return false;}// dfs递归static long dfs(int x){if(x == 1) return b[1];if(x == 2) return b[2];if(x == 3) return b[3];return dfs(x-1) + dfs(x - 2) + dfs(x - 3);}
}
📚法一
import java.util.*;public class Main {static int N = 10000000;public static void main(String[] args) {Scanner sc = new Scanner(System.in);for (int i = N; i >= 197; i--) {if(check(i)){System.out.println(i);break;}}}static boolean check(int x){String str = x + "";// 获取位数int len = str.length();// 数组大小为len就够用了int[] dp = new int[len];// 将 x 每一位都拆出来for (int i = 0; i < len; i++) {dp[i] = str.charAt(i) - '0';}// 数组求和int sum = 0;for (int i = len; sum < x ; i++) {sum = Arrays.stream(dp).sum(); // 数组求和,注意语法dp[i % len] = sum; // 后面用不到的下标元素 进行替换}return sum == x; // 两种结果:=x返回true,>x返回false}
}
每次求和其实只用到len个元素,所以可以对后续用不到的元素进行替换。
📚法二:
import java.util.*;public class Main {static int N = 10000000;public static void main(String[] args) {Scanner sc = new Scanner(System.in);for (int i = N; i >= 197; i--) {if(check(i)){System.out.println(i); // 7913837break;}}}// 检查是否是 类斐波那契 循环数static boolean check(int x) { // num是位数String str = x + "";int len = str.length();int sum = 0;ArrayList<Integer> a = new ArrayList<>();for (int i = 0; i < len; i++) {int num = str.charAt(i) - '0';a.add(num); // [1,9,7]sum += num;}//上面的这个循环究竟是在干什么事情:下面的这个以1234为例子说明,方便理解//列表 a 存储了整数 1234 的各个数位数字 [1, 2, 3, 4],// 变量 sum 的值为 10,即整数 1234 各个数位数字的总和。a.add(sum);// 此时变成了[1, 2, 3, 4,10]if(sum == x) return true;while(sum < x){//乘以2减去这个里面的第一个元素就是这个类斐波那契数列的规律,避免使用纯粹的数学方法计算sum = sum * 2 - a.get(0); a.remove(0);a.add(sum);if(sum == x) return true;}return false;}
}
思想:要求
第k+1位以后的数
只需将k
乘以2减去这个里面的第一个元素就是这个类斐波那契数列的规律,避免使用纯粹的数学方法计算。
第三题:分布式队列
👇写成这样有9个样例过不了,因为没有考虑副队列不超过主队列。
import java.util.*;public class Main {static int N = 2010;static int INF = 100005;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] a = new int[n];while(sc.hasNext()){String str = sc.next();if(str.equals("add")){int num = sc.nextInt();a[0] ++;}else if (str.equals("sync")){int num = sc.nextInt();a[num] ++;} else if (str.equals("query")) {int ans = INF;for (int i = 0; i < n; i++) {ans = Math.min(ans,a[i]);}System.out.println(ans);}}}
}
📚分布式队列
第四题:食堂
📚
import java.util.*;public class Main {static int N = 2010;static int INF = 100005;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int q = sc.nextInt();while(q-->0) {int a2 = sc.nextInt();int a3 = sc.nextInt();int a4 = sc.nextInt();int b4 = sc.nextInt();int b6 = sc.nextInt();int sum = 0;// 满座 匹配4人寝坐4人桌while(a4 != 0 && b4 != 0){a4 --;b4 --;sum += 4;}// 满座 匹配2x2人寝坐4人桌while(a2 != 0 && b4 != 0){a2 = a2 - 2;b4 --;sum += 4;}// 满座 匹配2+4人寝坐6人桌while(a2 != 0 && a4 != 0 && b6 != 0){a2 --;a4 --;b6 --;sum += 6;}// 满座 匹配2x3人寝坐6人桌while(a3 != 0 && b6 != 0){a3 = a3 - 2;b6--;sum += 6;}// 满座 匹配3x2人寝坐6人桌while(a2 != 0 && b6 != 0){a2 = a2 - 3;b6 --;sum += 6;}// 空1座 匹配3人寝坐4人桌while(a3 != 0 && b4 != 0){a3--;b4--;sum += 3;}// 空1座 匹配3+2人寝坐6人桌while(a3 != 0 && a2 != 0 && b6 != 0){a3--;a2--;b6--;sum += 5;}// 空2座 匹配2人寝坐4人桌while(a2 != 0 && b4 != 0){a2--;b4--;sum += 2;}// 空2座 匹配4人寝坐6人桌while(a4 != 0 && b6 != 0){a4--;b6--;sum += 4;}// 空2座 匹配2x2人寝坐6人桌while(a2 != 0 && b6 != 0){a2 = a2 - 2;b6--;sum += 4;}// 空3座 匹配3人寝坐6人桌while(a3 != 0 && b6 != 0){a3--;b6--;sum += 3;}// 空4座 匹配2人寝坐6人桌while(a2 != 0 && b6 != 0){a2--;b6--;sum += 2;}System.out.println(sum);}}
}
🍎
能想出来贪心策略就不难。想不出来可以试着骗分👇
if(sum1 > sum2){sout(sum2)
}else if(sum1 <= sum2){sout(sum1)
}
第五题:最优分组
第六题:星际旅行
📚星际旅行
第七题:LITS游戏
第八题:拼十字
⭐️考点总结:
1.数学+1
2.暴力 构造 枚举 +1
3.模拟+1
4.贪心+1