24年蓝桥杯javaB组
蓝桥杯在昨天考完了,结果很不乐观,哎,还是太笨了,脑子确实转的慢;😥
本篇博客中解题思路和代码并不一定完全正确,是我和同学们讨论的解答方法,但并未使用官方题解验证(此时官方题解还未出),笔者只是为各位提供一个思路,仅供参考;
如果各位有更好的方法或者该题解有错误,可以在评论区指出;
先写几道现在知道怎么写的;
文章目录
- 24年蓝桥杯javaB组
- A.报数游戏
- B.类斐波那契循环数
- C.分布式队列
- D.食堂
- E.最优分组
A.报数游戏
【题目描述】
【题目思路】
这道题先找规律,蓝桥杯前面的题都是有一定规律可循的,或者是一眼就能看出来能暴力解的;
我们能发现20和24的最小公倍数是120,又通过计算知道120里有10个符合条件的数(例如 1200就会有100个符合条件的,2400就会有200个符合条件的),所以就知道每120个数就要加10;若共有202420242024即202420242020+4个,所以排到第(202420242024/10) * 120+48(剩余四个数)= 202420242024*12;
【答案】:202420242024*12;
B.类斐波那契循环数
【题目描述】
【题目思路】
这个题目意思是,对于n位的数字,构成一个数组,数组前n位是数字的各位,后边的每一位都是该数前n位值之和;问:从1到10000000内的数字,形成的数组是否有数等于该数字的值,并取满足要求的最大的数字。🥯
反向推就可以了,因为是一道填空题,并不需于急于一口气做出来答案,先判断最大数,再往前判断;
这里有个小技巧,当数组加到40多位的时候已经完全大于10000000以内的数了。不再需要接着往下遍历,当然可以另外加一个判断:当前数组中的数大于循环的这个数时,直接进入下一个循环;
if(a[i]>k)
continue m;
【题目代码】
import java.util.Scanner;
//10000000
public class demo2 {
public static void main(String[] args) {
int n=10000000;
String s ;
m: for (int k = n; k > 0; k--) {
s = String.valueOf(k);//传入字符
int b = s.length();//判断传入的数长度是多少
int[] a = new int[50];//使用数组存s的每一位
for (int i = 0; i < b; i++) {
a[i] = s.charAt(i) - 48;
}
for (int i = b; i < 50; i++) {//因为可以经过判断
int c = 0;
for (int j = i - b; j < i ; j++) { //数字的每一位
c = a[j] + c;
}
a[i] = c;
if(a[i]>k)
continue m;
if(a[i]==k) {
System.out.println(a[i]);
return;
}
}
}
}
}
【运行结果】:7913837
C.分布式队列
【题目描述】
【题目思路】
这道题很多人纠结于程序如何结束,题目中并没有详细给出,所以好多人做起来很难受,不知道如何下手,其实没结束那就不结束就好了,每次进行查询操作,都把最新的同步输出去就行了,即程序输入并不需要结束运行,而是做到边输入边输出;
除去这些,这道题其实就是一道描述题,使用代码复述文字描述就可以了;
【题目代码】
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();//输入表示有N个节点;
scanner.nextLine();
int c;
int []b=new int[N];//表示每个队列的长度,则 b[0]就表示主队列了
for (int i = 0; i <2000; i++) {//题目中说操作数最大为2000次;
String s=scanner.next();
if(s.equals("add")) {
c=scanner.nextInt();
b[0]=b[0]+1;
}
if(s.equals("sync")) {
c=scanner.nextInt();
b[c]=b[c]+1;
if(b[c]>b[0]){
b[c]=b[0];
}
}
if(s.equals("query")) {
int[] d = Arrays.copyOf(b, b.length);
Arrays.sort(d);
System.out.println(d[0]);
}
}
scanner.close();
}
}
D.食堂
【题目描述】
【解题思路】
这道题要先想到分桌子而不是分人,而且应该从6人桌开始分,分完六人桌分四人桌,具体全部情况:
思路:先分桌子,桌子一个一个分, 先分6人桌:3+3,4+2,2+2+2,3+2, 4,3; 把桌子全用完
再分4人桌:(4,2+2,3,2);
是不是醍醐灌顶?瞬间就清晰了?这个方法确实不错,而且实在是想不到反例了;
【题解代码】
import java.util.Scanner;
public class 食堂 {
//思路:先分桌子,桌子一个一个分, 先分6人桌:3+3,4+2,2+2+2,3+2,4,3,2; 把桌子全用完
// 再分4人桌:4人寝,2*2人寝,用完后3人寝 (4,2+2,3,2);
//
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int q=scanner.nextInt();
int []a=new int[q];
int []a2=new int[q];
int []a3=new int[q];
int []a4=new int[q];
int []b4=new int[q];
int []b6=new int[q];
m: for (int i = 0; i <q ; i++) {
a2[i]=scanner.nextInt();
a3[i]=scanner.nextInt();
a4[i]=scanner.nextInt();
b4[i]=scanner.nextInt();
b6[i]=scanner.nextInt();
for (int j = 0; j <b6[i]; j++) {
if (a3[i]>=2){
a3[i]=a3[i]-2;
a[i]=a[i]+6;
} else if (a4[i]>0&&a2[i]>0) {
a4[i]=a4[i]-1;
a2[i]=a2[i]-1;
a[i]=a[i]+6;
}else if(a2[i]>=3){
a2[i]=a2[i]-3;
a[i]=a[i]+6;
}else if(a3[i]>0&&a2[i]>0){
a2[i]=a2[i]-1;
a3[i]=a3[i]-1;
a[i]=a[i]+5;
}else if (a4[i]>0){
a4[i]=a4[i]-1;
a[i]=a[i]+4;
}else if(a2[i]>=2){
a2[i]=a2[i]-2;
a[i]=a[i]+4;
} else if(a3[i]>0){
a3[i]=a3[i]-1;
a[i]=a[i]+3;
}else if(a2[i]>0) {
a2[i] = a2[i] - 1;
a[i] = a[i] + 2;
}
else continue m;
}
for (int j = 0; j < b4[i]; j++) {
if(a4[i]>0){
a[i]=a[i]+4;
a4[i]=a4[i]-1;
}
else if(a2[i]>=2){
a[i]=a[i]+4;
a2[i]=a2[i]-2;
}
else if(a3[i]>0){
a[i]=a[i]+3;
a3[i]=a3[i]-1;
}else if(a2[i]>0){
a[i]=a[i]+2;
a2[i]=a2[i]-1;
}else continue m;
}
}
for (int i = 0; i < q; i++) {
System.out.println(a[i]);
}
}
}
E.最优分组
【解题思路】
这道题和高考数学中大题很像,其实只用模拟就完事了;首先每组K个人,那么一共有N/K个组,遍历K从小到大改变,计算每次的期望,期望算法:感染概率为p,那么没感染概率为(1-p),一个组中,所有人都没感染概率Math.pow((1-p),i);所以一个组中,至少一个人感染的概率是p1=1-Math.pow((1-p),i);所以总期望就知道了p1*N+每个组检查一次(N/k);
这道题有一个小坑,就是当k=1时,代入公式计算会将期望值算大,因为单人一组,并不需要对小组进行二次检查,所以例外:
当k=1时,期望直接就时N;
【题解代码】
import java.util.Scanner;
public class 最优分组 {
public static void main(String[] args) {
//满满的高考题既视感有没有,(暴漏年龄了);确实和高考题思路一样
//将N个宠物分组,每组K只宠物,则分N/K组,K肯定是N的因子;
Scanner scanner=new Scanner(System.in);
int N=scanner.nextInt();
double p=scanner.nextDouble();
{
double q=1-p;
double s=N+1;
int k=1;
for (int i = 1; i <=N; i++) {//i设置为k
if(i==1){s=N;k=1;}//当k=1时,期望直接就时N;
else if(N%i==0){
double p1=1-Math.pow(q,i);//每组感染的概率;
if(p1*N+N/i<s)
{
s=p1*N+N/i;
k=i;
}
}
}
System.out.println(k);
}}
}