(第一个填空太简单,就不写了,根本不用代码,直接excel计算)
目录
[蓝桥杯JAVA.b组第三题 -分布式队列(模拟)](#蓝桥杯JAVA.b组第三题 -分布式队列(模拟))
蓝桥杯第二个填空,类斐波那契循环数
首先难点就是这个题目需要读懂,当初我就是没读明白,才没写出来,我一般都是写力扣的题,力扣的题更加偏向于方法,或者说是业务上的,而蓝桥杯更偏向那种数学的类型
这个难点是弄懂那个求和符号,我好久没学,都忘了
比如说9999999这个是7位数,然后假如我们写第10位,就是
public static void main(String[]args) { for(int i=10000000;i>=0;i--){ char[] a=(i+"").toCharArray(); int sum=0; int[]b=new int[a.length]; for(int j=0;j<a.length;j++){ b[j]=Integer.valueOf(a[j]+""); sum+=b[j]; } while(true) { if (sum == i) { System.out.println(sum); return; } else if (sum > i) { break; } int tmp=sum; sum = 2 * sum - b[0]; for (int j = 0; j < a.length - 1; j++) { b[j] = b[j + 1]; } //更新最后一个值 b[a.length - 1] = tmp; //处理前一个值,进行迭代处理 } }
蓝桥杯JAVA.b组第三题 -分布式队列(模拟)
这个代码是我觉得看的最清晰的一个,而且他的想法很简洁,适合我这种菜鸡
这个题难度就是你选择的问题,你假如选择不正好的策略,会麻烦好多。像是我开始想用数组,因为下标不好表示,(开始我也是寻思用集合,但是困在一些问题上,选择自己更擅长的,但是确没想到更麻烦,而且没解出来)
public static void main(String[]args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//使用一个类似二维数组
List<List<Integer>> nums=new ArrayList<>();
for(int i=0;i<n;i++){
//这个数组有添加n个队列
nums.add(new ArrayList<>());
}
while (sc.hasNext()) {
//通过command判断输入的例子。
String command = sc.next();
if (command.equals("add")) {
int num=sc.nextInt();
//假如此时需要添加元素,则需要在第一个集合里面添加元素
nums.get(0).add(num);
} else if (command.equals("sync")) {
//获取到我们需要添加到哪号队列
int seq = sc.nextInt();
//nums获取到这个队列,假如里面的个数小于一号队列个数
if(nums.get(seq).size()<nums.get(0).size()) {
//nums的seq队列添加队列0里面的获取的是队列2的长度,队列2的下标永远是没到这个位置,所以需要到2号这个下标
nums.get(seq).add(nums.get(0).get(nums.get(seq).size()));
}
} else {
//找到n个队列中到元素个数
int min_count = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
//获取到每个元素,然后min代表最后的元素,模拟(很牛逼的思路,第二个)
if (nums.get(i).size() < min_count) min_count = nums.get(i).size();
}
System.out.println(min_count);
}
}
}
食堂(蓝桥杯D题)
这个题看着就恶心的模拟,但是假如说暴力穷举肯定也是可以,但是缺点是什么呢?
缺点就是她这个你很容易有想不到的情况,而且这些情况加一起,的顺序性就很恶心
所以相比较之下,还是下面这个方法更好
这道题我相信大部分人的思路肯定是从食堂桌子出发,那么我们需要做的就是分解他条件的思考
首先4个桌子,6个桌子,我们肯定是第一时间,先凑出来6人桌子,2个三人桌肯定是最优先,然后我们考虑的是什么,2+4肯定6个,2+2+2肯定6个,但是假如换个思路,假如已经坐了两个人,我们是不是可以默认这个食堂多了一个四人桌子,如果这么考虑,我们很多情况都可以合并到一起,只需要考虑四人桌子就行,
四人桌子肯定还是优先4人和2个2人,假如这些都完事了,说明什么情况呢,
存在六人桌子,存在4人和3人,但是不存在2人
存在4人桌子,可能存在两个人,可能存在三个人,(有人可能问我们在开始就判断了是否可能出现2个人,结果是一定不会有两个人,但是假如没有六人桌子的情况下,是否有可能出现2个人呢,也是有可能的)
这些情况综合起来只有一句话,就是一个桌子只能坐一个寝室,你2人,3人,4人都好
我只要把最后的桌子都放到一起,然后4人就给一个桌子(不管它是4人还是6人,反正一定能装下)
(这里补充:可能你觉得不靠谱,去试试假如5个人咋整,(5个人的前提是有2个人,2个人要么我存在6人桌子被分开,要不存在六个人的桌子,那样坐不了五个人,所以还是一个桌子一个寝室)
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[]args) {
Scanner scan = new Scanner(System.in);
int q=scan.nextInt();
int[][]a=new int[q][5];
//选择的角度应该是从桌子入手,
//a[0][0]:两人寝室,[1]三人寝室,[2]四人寝室 [3]四个人桌子[4]六人桌子
//更优秀的思想,把六个人的桌子转化为四个人的桌子
for(int i=0;i<q;i++){
for(int j=0;j<5;j++){
a[i][j]=scan.nextInt();
}
int count=0;
//a[0][0]:两人寝室,[1]三人寝室,[2]四人寝室 [3]四个人桌子[4]六人桌子
//假如有六人桌子优先分配2个三人
while(a[i][4]>0&&a[i][1]>=2){
a[i][1]-=2;
a[i][4]--;
count+=6;
}
//假如有六人桌子优先分配1个两人,这样,就相当于多了一个四个人的桌子
while(a[i][4]>0&&a[i][0]>0){
a[i][4]--;
a[i][0]--;
a[i][3]++;
//相当于多了一个四人桌子
count+=2;
}
//假如四人桌子优先分配四个人的
while(a[i][3]>0&&a[i][2]>0){
a[i][2]--;
a[i][3]--;
count+=4;
}
//四人寝室没了,四人桌子优先给2个2人寝室
while(a[i][3]>0&&a[i][0]>=2){
//2人寝室则剪去2个
a[i][0]-=2;
a[i][3]--;
count+=4;
}
//到了最后其实就都不是凑整数的情况,换句话说,咋吗都坐不满,6人能转化的,都转化了,转化不了的,也同化成4个人
//因为假如你想5个人是3+2,相当于四人寝室住了3个人,换句话,最后四人桌子还是六人桌子已经没有区别了
int num=a[i][4]+a[i][3];
//以下的情况都是满足不了的
while(num>0&&a[i][2]>0){
num--;
a[i][2]--;
count+=4;
}
while(num>0&&a[i][1]>0){
num--;
a[i][1]--;
count+=3;
}
while(num>0&&a[i][0]>0){
num--;
a[i][0]--;
count+=2;
}
System.out.println(count);
}
scan.close();
}
}
最优分组(数学题)
星际旅行(Floyd佛洛依德)
static int n,m,q;
static int[][] con;
public static void main(String[] args) {
Scanner zh=new Scanner(System.in);
n=zh.nextInt();
m=zh.nextInt();
q=zh.nextInt();
con=new int[n+1][n+1];//我们选择从[1-n]闭区间,不考虑0
//处理边界值比如0x之类的
for(int i=1;i<=n;i++)Arrays.fill(con[i], 3010);
for(int i=1;i<=n;i++)con[i][i]=0;
for(int i=0;i<m;i++) {
int a=zh.nextInt();
int b=zh.nextInt();
con[a][b]=1;
con[b][a]=1;
}
//算法核心,核心问题也在这里k在最外面和k在循环的最里面有什么区别
for(int k=1;k<=n;k++) {
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
//这个的核心是类似于动态规划从con[i][j],con[i][k]+[k][j],从i到j,需要i通过k到j
//相当于算从i到j位置的最短路径,
con[i][j]=Math.min(con[i][j], con[i][k]+con[k][j]);
}
}
}
int ans=0;
for(int i=0;i<q;i++) {
int x=zh.nextInt();
int y=zh.nextInt();
int count=0;
//我们从x点出发,到达j点花费步骤假如小于y就说明可以到达,count++;
for(int j=1;j<=n;j++)if(con[x][j]<=y)count++;
//System.out.println(count);
ans+=count;
}
System.out.printf("%.2f", (double)ans/q);
}