2024年第十五届蓝桥杯JavaB组赛后复盘与总结

文章记录了一位参赛者在蓝桥杯编程比赛中遇到的几道题目,包括使用暴力枚举解法的报数游戏、类斐波那契循环数、分布式队列处理字符串输入以及食堂问题的优化策略。作者强调比赛中的学习与反思,虽然不是最优解但展示了比赛过程。
摘要由CSDN通过智能技术生成

目录

A:报数游戏

 B:类斐波那契循环数​编辑

C:分布式队列

D:食堂

E;最优分组

FG题略

H:拼十字


序 

文章写于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);
    }
}

测试用例也是跑出来了,但是压轴题不能这么简单吧

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不爱吃于先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值