蓝桥杯2016-2022年B组省赛第2题汇总讲解

总结:

2016:求生日蜡烛。 暴力循环

2017:等边三角形排法。 全排列(递归)/暴力循环

2018:圆内完整小方格数。 暴力循环

2019:不同子串。 暴力循环、字符串

2020-1:某两天间分钟。 函数的掌握

2020-2:大型矩阵中找2020。 暴力循环

2021:数字卡片。 暴力循环、数字分割

2022:“山”型数字。 暴力查找

综上:第二题普遍数据量特别大,直接排除学生口算或能一眼看出来的可能。

如果第一题可以借助工具或一眼看出答案,那么第二题就得通过简单编程实现了。

通过分析近些年题型,对于第二题只要能看懂题目、知道总体解题思路、会简单循环和判断(即暴力算法)就能做出来。

主要考察:1、循环,而且很可能是暴力循环(数据量很大)(如:2016年、2017年、2018年、2020年-2、2021年、2022年)

2、字符串各种函数功能(字符和数字间的转换函数)(如:2019年、2020年-1、2020年-2、2022年)

3、数学思维(全排列、求圆半径公式、等边三角形三边相等)(如:2016年、2017年、2018年、2021年、2022年)

4、找规律(如:2016年、2017年)

接下来列出2016年-2022年间第2题的详细讲解:


2016年

某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。现在算起来,他一共吹熄了236根蜡烛。请问,他从多少岁开始过生日party的?

请填写他开始过生日party的年龄数。

注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

public static void main(String[] args){
int x;//蜡烛数
    for(int i=1;i<50;i++){//从1岁开始计算,50是一个大概上限
        x=i;
        for(int j=i+1;j<50;j++){//遍历之后每年
            x+=j;//i到j年间(包括第j年)蜡烛总数
            if(x>236)break;
            if(x==236){//找到
                System.out.println(i);
                break;
            }
        }
    }
}
答案:26

思路:(暴力算法)从第一岁开始,一年一年地计算,直到遍历到符合题目地年龄。

2017年

A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。下图就是一种排法。这样的排法可能会有很多。如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?

      A
     9 6
    4   8
   3 7 5 2

请你计算并提交该数字。

注意:需要提交的是一个整数,不要提交任何多余内容。

方法一:暴力算法。
public static void main(String[] args){
        int count=0;
        for(int a=1; a<=9;a++) {
            for(int b=1; b<=9; b++) {
                for(int c=1;c<=9;c++) {
                    for(int d=1;d<=9;d++) {
                        for(int e=1;e<=9;e++) {
                            for(int f=1;f<=9;f++) {
                                for(int g=1; g<=9;g++) {
                                    for(int h=1;h<=9;h++) {
                                        for(int i=1;i<=9;i++) {
                                            if(a!=b&&a!=c&&a!=d&&a!=e&&a!=f&&a!=g&&a!=h&&a!=i&&
                                                    b!=c&&b!=d&&b!=e&&b!=f&&b!=g&&b!=h&&b!=i&&
                                                    c!=d&&c!=e&&c!=f&&c!=g&&c!=h&&c!=i&&
                                                    d!=e&&d!=f&&d!=g&&d!=h&&d!=i&&
                                                    e!=f&&e!=g&&e!=h&&e!=i&&
                                                    f!=g&&f!=h&&f!=i&&
                                                    g!=h&&g!=i&&
                                                    h!=i) {
                                                if((a+b+d+f)==(a+c+e+i)&&(a+c+e+i)==(f+g+h+i)) count++;}}}}}}}}}}
        System.out.println(count/6);
}
方法二:全排列(递归)(不太好理解)
public static void main(String[] args) {
        dfs(0);
        System.out.println(ans/6);//
    }
    
    static int[] a = new int[] {1,2,3,4,5,6,7,8,9};
    static int ans = 0;
    
static void dfs(int m) {
    if(m>=9) {
        if(a[0]+a[1]+a[3]+a[5]==a[0]+a[2]+a[4]+a[8]&&a[0]+a[2]+a[4]+a[8]==a[5]+a[6]+a[7]+a[8])
            ans++;
        
        return;
    }
    
    for(int i=m;i<9;i++) {
        swap(i,m);
        dfs(m+1);
        swap(i,m);
    }
        
    }
    
static void swap(int i,int j) {
    int t = a[i];
    a[i] =a[j];
    a[j] = t;
}
 
}
答案:144

思路:先固定一位数,其余数全排列。循环直到每一位数都在每个位置上被固定过。

比如对数组a={1,2,3,4},其全排列为:1234、1243、1324、1342、1423、1432

2134、2143、2314、2341、2431、2413..........

全排列讲解请移步:全排列

总上对递归分析如下:(图点开放大看)

由于每个位置固定情况下通过旋转和镜像有6种情况相同,所以对计算结果除6即为答案。

2018年

如图所示,在二维平面上有无数个1x1的小方格。我们以某个小方格的一个顶点为圆心画一个半径为1000的圆。你能计算出这个圆里有多少个完整的小方格吗?

public static void main(String[] args){
        int sum=0;
        for(int i=1;i<1000;i++){
            for(int j=1;j<1000;j++){
                if(i*i+j*j<=1000*1000)sum++;
            }
        }
        System.out.println(sum*4);
答案:3137548

思路:对1/4圆进行分析。由a^2+b^2=r^2公式进行计算,求得1/4圆内完整的小方格。结果再乘4就是整个圆内完整的小方格数。

2019年

一个字符串的非空子串是指字符串中长度至少为 1连续的一段字符组成的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共 7 个。注意在计算时,只算本质不同串的个数

请问,字符串0100110001010001 有多少个不同的非空子串?

public static void main(String[] args){
    String str="0100110001010001";
                HashSet<Object> set = new HashSet<>();
        for(int i=0;i<str.length();i++){
            for(int j=i;j<str.length();j++){
                String s=str.substring(i,j+1);//将字符串从i位置分割,并保存i之后字符串在set中
                set.add(s);
            }
        }
                System.out.println(set.size());
}
答案:100

思路:使用哈希substring方法直接将字符串进行分割并保存。最后通过size求其数量。

2020年-1

2020 年 7 月 1 日是中国共产党成立 99 周年纪念日。中国共产党成立于 1921 年 7 月 23 日。

请问从 1921 年 7 月 23 日中午 12 时2020 年 7 月 1 日中午 12 时一共包含多少分钟

public static void main(String[] args) throws ParseException {
        DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//定义时间格式
        Date start=format.parse("1921-7-23 12:00:00");//将文本时间转为Date时间型
        Date end=format.parse("2020-7-1 12:00:00");
        long x= ((end.getTime()-start.getTime())/1000/60);//除1000表示以秒为单位,除60表示以分为单位
        System.out.println(x);
}
答案:52038720

思路:利用DateFormat对象将时间文本转为时间格式并进行计算。

注意:y:年、M:月、m:分种、d:天、H:24小时制、h:12小时制、s:秒。

2020年-2

小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找到这个数字矩阵中有多少个 2020 。小蓝只关注三种构成 2020 的方式:同一行里面连续四个字符从左到右构成 2020。同一列里面连续四个字符从上到下构成 2020。在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。例如,对于下面的矩阵:

220000

000000

002202

000000

000022

002020

一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个是斜线上的。小蓝的矩阵比上面的矩阵要大,由于太大了,他只好将这个矩阵放在了一个文件里面,在试题目录下有一个文件 2020.txt,里面给出了小蓝的矩阵。请帮助小蓝确定在他的矩阵中有多少个 2020。

(以例子矩阵给出代码)

public static void main(String[] args){
    int m=6;
    int n=6;
    int sum=0;
    char[][] ch=new char[m][n];
    Scanner input=new Scanner(System.in);
    for(int i=0;i<m;i++){
        ch[i]=input.nextLine().toCharArray();
    }
    //横向找
    for(int i=0;i<m;i++){
        for(int j=0;j<n-3;j++){
            if(ch[i][j]=='2' && ch[i][j+1]=='0' && ch[i][j+2]=='2' && ch[i][j+3]=='0')
                sum++;
        }
    }
    //竖向找
    for(int i=0;i<m-3;i++){
        for(int j=0;j<n;j++){
            if(ch[i][j]=='2' && ch[i+1][j]=='0' && ch[i+2][j]=='2' && ch[i+3][j]=='0')
                sum++;
        }
    }
    //斜向找
    for(int i=0;i<m-3;i++){
        for(int j=0;j<n-3;j++){
            if(ch[i][j]=='2'&&ch[i+1][j+1]=='0'&&ch[i+2][j+2]=='2'&&ch[i+3][j+3]=='0')
                sum++;
        }
    }
System.out.println(sum);
}
答案:5

思路:分别从三个放向进行查找(横向、竖向、斜向),如果满需要求就计数。

2021年

小蓝有很多数字卡片,每张卡片上都是数字0 到9。小蓝准备用这些卡片来拼一些数,他想从1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。小蓝想知道自己能从1 拼到多少。

例如,当小蓝有30 张卡片,其中0 到9 各3 张,则小蓝可以拼出1 到10,但是拼11 时卡片1 已经只有一张了,不够拼出11。现在小蓝手里有0 到9 的卡片各2021 张,共20210 张,请问小蓝可以从1拼到多少?提示:建议使用计算机编程解决问题。

public static void main(String[] args){
        int[] array=new int[10];//数组array每个值表示0-9数字的个数
        Arrays.fill(array,2021);//将数组array所有值设为2021
        for(int i=1;;i++){
            int temp=i;
            while (temp>0){//循环数字的每一位寻找数字卡片
                int r=temp%10;//取数的最后一位
                if(array[r]>0)//如果该数字卡片还有则使用一张
                    array[r]--;
                else {//该数字卡片用完了,表示达到最大拼出的数字,退出程序
                    System.out.println(i-1);
                    return;
                }
                temp/=10;//去掉最后一位循环找剩下数字的卡片
            }
        }
}
答案:3181

思路:数组a中存放1~9每张卡片的个数,从1开始进行拼图,用完一个数字该数组-1,直到数组内任意一个数字卡片个数为0。

2022年

这天小明正在学数数。他突然发现有些正整数的形状像一座“山”,比如 123565321 、 145541 ,它们左右对称(回文)且数位上的数字先单调不减,后单调不增。小明数了很久也没有数完,他想让你告诉他在区间[2022,2022222022]中有多少个数的形状像一座“山”。

public static void main(String[] args) {
    int count = 0;
    for (int i = 2022; i <= 2022222022; i++) {//循环区间内所有数字
        if(isHuiWen(i)&&isDiZenDiJian(i))//满足条件则计数
            count++;
    }
    System.out.println(count);
}
public static boolean isHuiWen(int sum){//判断回文
    StringBuilder str=new StringBuilder(sum+"");
    return (str.reverse().toString()).equals(sum+"");//正序与反序对比是否相等
}
public static boolean isDiZenDiJian(int sum){//判断递增递减
    String s=sum+"";
    int mid=s.length()%2==0?s.length()/2:s.length()/2+1;//求数字中间下标
    for(int i=0;i<mid-1;i++){//从头到中间判断是否满足递增要求
        if(s.charAt(i)>s.charAt(i+1))
            return false;
}
    return true;
}
答案:3138

思路:对区间内的每个数字进行回文和递增判断,符合要求则计数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值