目录
序
文章写于2024年4月16日,蓝桥杯考完还没出结果,获奖结果与于2024年5月5日上传到文章开头
蓝桥杯第一次参加,对算法这些东西挺感兴趣,而且大三了打算考研,报名的时候(n个月之前)想到正好要复习一下数据结构,时间来算正好能学玩去参加一下蓝桥杯,就当阶段性考试了,整不好还能拿个奖(因为之前的朋友说 这东西就是花钱买省三,很水)
这次比赛感觉比去年的简单多了,这东西是不是一年简单一年难.
因为学习编程相关的东西的时候习惯复盘和总结,所以写下这篇文章,文章只是本人记录自己在比赛时的想法与赛后的马后炮,所有代码都是比赛时候写出来的复制到这里了,时间紧张 变量名称都是随便起的,算法也不是最简单,时空复杂度最低的,答案也不一定对(这是真的)各位大佬勿喷
参加完蓝桥杯,正好开始计算机组成原理的学习了
A:报数游戏
有点抽象了这道题,当时第一次进去参加这种比赛有点小紧张其实,然后一看到题目满脑子想的都是暴!!!力!!!枚!!!举!!!,好,那就暴力枚举!!!
好,翻了一下电脑,暴力枚举的算法删了,总之当时是没跑通,说是找到第202,420,242,024个,我找到一个就输出一个i,代码运行时候电脑都起飞了,第二题都跑出来了,一看半小时过去了,才跑到了500,000,000,还得跑好多个半小时,拉倒吧,遂终.
做到后面了 发现,这个好像有规律啊,先跑2024个看看吧
public class test {
//2,429,042,904,288
public static void main(String[] args) {
long sum=2024l;
long e=0;
long i=0;
while (true){
i++;
long zhuzi=i;
if (zhuzi%20==0||zhuzi%24==0){
System.out.print(i/4+" ");
e=e+1;
}
if (e==sum) break;
}
}
}
输出
果然有规律,放到文本文档里
这不是正好10个一组,一组加30(之前除过4,因为数字越小规律越好找),所以直接计算出来了答案
(我直接好家伙,我恨死你这个window的计算器了,去idea里面复制答案的时候我一看怎么还带,了,我才想起来输入答案的时候是直接从计算器复制的,!!!!!!也不知道这种算不算对)
2,429,042,904,288
B:类斐波那契循环数
没有技巧全是暴力枚举:
代码:
import java.util.ArrayList;
import java.util.List;
public class test {//7913837
public static void main(String[] args) {
//getfbnaqie(197);
ArrayList<Integer> objects = new ArrayList<>();
for (int i = 197; i <= 10000000; i++) {
int shuzi=i;
if (getfbnaqie(shuzi)) objects.add(i);
}
for (int i = 0; i < objects.size(); i++) {
System.out.println(objects.get(i));
}
// System.out.println(objects.get(objects.size() - 1));
}
static boolean getfbnaqie(int n){
int weishu=0;
int shuzi=n;
ArrayList<Integer> ints = new ArrayList<>();
while (n!=0){
int a=n%10;
ints.add(a);
weishu++;
n=n/10;
}
for (int i = 0; i < ints.size() / 2; i++) {
int temp=ints.get(ints.size()-1-i);
ints.set(ints.size()-1-i,ints.get(i));
ints.set(i,temp);
}
for (int i = 0; ; i++) {
int sum=0;
for (int j = i; j < i+weishu; j++) {
sum+=ints.get(j);
}
ints.add(sum);
if (sum>shuzi)break;
}
// for (int i = 0; i < ints.size(); i++) {
// System.out.println(ints.get(i));
// }
// Integer integer = Integer.valueOf(n);
return ints.contains(shuzi);
}
}
主函数里面有一个枚举函数,通过了的数字添加到ArrayList里面,主函数调用的函数是循环判断是否是类斐波那契循环数的函数,其实就是把这个数字的各个位拆分,记录位数n,然后不断把后n个数字相加,得到的数字加到Array List里面,如果比原数字大了,就跳出,判断原数字是否contains这个数组,然后返回boolean变量,
输出
为什么全部输出?当然是要看一下题目给的197有没有计算出来,要是没有197就直接回去改代码吧:
C:分布式队列
这个题目咱也是直接投机取巧了,把输入的看成一整个字符串,因为对Scanner缓冲区学习的不到位,用了一个if去判断了一下,如果输入的不是打印操作,那就再输入一个数字,然后队列的记录其实是用了一个2维数组桶,再设置了一个一维数组去记录长度,同步的时候要注意,只有长度比第一队列短的时候 才能去同步(比赛时没想到这一点,其实是题目里的输入样例给了提示,初代代码报错了我才发现这个问题)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();
int lengtn[]=new int[N];
for (int i = 0; i < N; i++) {
lengtn[i]=-1;
}
int queu[][]=new int[100000][N];
String s;
String caozuoshu="";
while (true){
s=scanner.next();
char[] testchar = s.toCharArray();
if (testchar[0]!='q') caozuoshu=scanner.next();
s=s+caozuoshu;
char[] chars = s.toCharArray();
if (chars[0]=='a'){
queu[lengtn[0]+1][0]=chars[3]-48;
lengtn[0]++;
}
if (chars[0]=='s'){
int index=chars[4]-48;
if (lengtn[index]<lengtn[0]){
queu[lengtn[index]+1][index]=queu[lengtn[lengtn[index]+1 ]][0];
lengtn[index]++;
}
}
if (chars[0]=='q'){
int min=99999;
for (int i = 0; i < N; i++) {
if (lengtn[i]<min){
min=lengtn[i];
}
}
System.out.println(min + 1);
}
}
}
}
D:食堂
不会,暴力枚举,有好多种情况
2去4,22去4,3去4,4去4,222去6,2去6,22去6,33去6,3去6.........
只会这么枚举了,但是也不能真的去笨蛋枚举法把,这些情况是有优先级的,能全部消耗完一张桌子的情况肯定要放在前面属于T0队列,然后属于23去6这种剩一个位置的属于T1队列,剩的更多的 再往后,这样虽然也是枚举,但是正确性能更高一点
代码:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
ArrayList<Integer> integers = new ArrayList<>();
int n=scanner.nextInt();
for (int i = 0; i < n; i++) {
int jisuan = jisuan();
integers.add(jisuan);
}
for (int i = 0; i < integers.size() ; i++) {
System.out.println(integers.get(i));
}
}
public static int jisuan (){
Scanner scanner=new Scanner(System.in);
int sumStudent=0;
int a2=scanner.nextInt();
int a3=scanner.nextInt();
int a4=scanner.nextInt();
int b4=scanner.nextInt();
int b6=scanner.nextInt();
//1
int siqusi=0;
int ersanquliu=0;
int erqusi2=0;
int sanquliu1=0;
int sanquliu2=0;
int erquliu3=0;
int erquliu2=0;
int erquliu1=0;
int erqusi1=0;
int siquliu=0 ,sierquliu=0, sanqusi=0;
//siqusi
while (a4>0&&b4>0){
siqusi+=4;
a4-=1;
b4-=1;
}
while (a2>2&&b6>0){
erquliu3 += 6;
a2-=3;
b6-=1;
}
//erqusi 2
while (a2>1&&b4>0){
erqusi2+=4;
a2-=2;
b4-=1;
}
while (a2>0&&a4>0&&b6>0){
sierquliu+=6;
a4--;
a2--;
b6--;
}
//sanquliu2
while (a3>1&&b6>0){
sanquliu2+=6;
a3-=2;
b6-=1;
}
//erquliu
while (a2>0&&a3>0&&b6>0){
ersanquliu+=5;
a2--;
a3--;
b6--;
}
while (a2>0&&b4>0){
erqusi1 += 2;
a2-=1;
b6-=1;
}
while (a2>1&&b6>0){
erquliu2 += 4;
a2-=2;
b6-=1;
}
//int siquliu=0 ,sierquliu=0, sanqusi=0
while (a4>0&&b6>0){
siquliu+=4;
a4--;
b6--;
}
while (a3>0&&b4>0){
sanqusi+=3;
a3--;
b4--;
}
sumStudent= siqusi+ erqusi2+ sanquliu1+ sanquliu2+ erquliu3+ erquliu2+
erquliu1+ erqusi1+ ersanquliu+siquliu+sierquliu+sanqusi;;
return sumStudent;
}
}
E;最优分组
高中数学题好吧,直接也就是一个暴力枚举(蓝桥杯的真谛就是暴力枚举)题目说每组恰好K个宠物,也就是说应该是正好整除的(没看见的挨打)那么我们N%K!=0的时候直接continue,(这题应该数大一点就会超时了,但是测试用例是跑出来了)
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//System.out.println(cifang(0.1, 2));
ArrayList<Integer> integers = new ArrayList<>();
double summin=999999999;
int k=0;
Scanner scanner=new Scanner(System.in);
int N=scanner.nextInt();
double p=scanner.nextDouble();
for (int K = 1; K <=N ; K++) {
if (N%K!=0) continue;
// System.out.println(K);
double total=(cifang(1-p,K)+(1-cifang(1-p,K))*(K+1))*(N/K);
// System.out.println(total);
if (total<summin) {
k=K;
summin=total;
}
}
System.out.println(k);
}
public static double cifang(double p,int n){
double sum=1;
for (int i = 0; i < n; i++) {
sum*=p;
}
return sum;
}
}
FG题略
别问为什么略
竟然忘记了直接输出一波题目给的测试用例来骗分了,大失误.
H:拼十字
不说了,又得用蓝桥杯真谛了,暴力枚举
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long sum=0l;
int N=scanner.nextInt();
int a[][]=new int[N][3];
for (int i = 0; i < N; i++) {
a[i][0]=scanner.nextInt();
a[i][1]=scanner.nextInt();
a[i][2]=scanner.nextInt();
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i==j)continue;
if (a[i][0]>a[j][1]&&a[i][1]<a[j][0]&&a[i][2]!=a[j][2]) sum+=1;
if (a[i][0]<a[j][1]&&a[i][1]>a[j][0]&&a[i][2]!=a[j][2]) sum+=1;
}
}
System.out.println((sum/2)%1000000007);
}
}
测试用例也是跑出来了,但是压轴题不能这么简单吧