【蓝桥真题1】这道用了7个for循环的蓝桥真题,让舍友哭着跑出考场【内附原题资源】(上)

简介: 特意选取了蓝桥往年真题中许多能体现出蓝桥经典题型的题目——如暴力遍历、枚举、动态规划等等。其中最主要的还是枚举,枚举题目在蓝桥杯中是最热的考点且没有之一。可以说把枚举练好,就已经半只脚踏入了国赛的大门。有需要的兄弟们可以收藏一下,后续我会继续更新蓝桥真题题型专栏,和大家一起冲击蓝桥杯。下面的真题建议大家先自行思考后再看答案。原题视频资源在文章结尾。

🍋1.蓝桥刷题须知


       蓝桥杯比赛并不像我们平时在力扣和牛客网刷题一样,对我们代码运行和时间有着限制。Java组采用的是eplipse编译器,C/C++才用的是DevC++。填空题我们需要在编译器中自己跑出答案,然后直接提交答案即可。所以大家不要担心什么啊这个代码难道不会超时吗,这个代码空间复杂度也太大了吧,人家只看你的答案是否正确,就算你把电脑跑烂了都没问题,所以要大胆尝试。


🍋2.经典例题讲解


🚀1.世纪末的星期(经典日期API问题)


        题目:有邪教称1999年12月31日是世界末日,当然谣言已经不攻自破。还有人称今后的某个世纪末的12月31日,如果是星期一则会....有趣的是,任何一个世纪末的年份的12月31日都不可能是星期一!!!于是"谣言制造商"又修改为星期日.......


       1999年12月31日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即XX99年)的12月31日正好是星期天(即星期日)? 回答年份即可        


public class 世纪末的星期 {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        for (int year = 1999; year <10000 ; year+=100) {
            calendar.set(Calendar.YEAR,year);
            calendar.set(Calendar.MONTH,11);//其实是12月
            calendar.set(Calendar.DAY_OF_MONTH,31);
            if (calendar.get(Calendar.DAY_OF_WEEK)==1) {
            //sunday是第一天,所以为1时是Sunday,通过源码查看
                System.out.println(year);// 2299
                break;
            }
        }
    }
}

      🔑解析:之所以要讲这道经典例题,是因为日期问题是蓝桥杯的高频考点。Java组在这种题目占尽便宜,因为Java中有着Calendar这个日期API,这是非常重要的。它能几乎解决与日期相关的所有问题。这里我们通过设置年月份,然后判断是否是星期天,如果是则直接输出答案,非常简单。如果这题不使用CalendarAPI的话,还是非常麻烦的,所以Java组的小伙伴一定要学会。        


🚀2.马虎的算式(五个for循环枚举问题)


       题目:小明是个急性子,上小学的时候经常抄错题目。有一次老师出的36X495=?他却抄成了396X45?但结果却很戏剧性,他的答案是正确的!!因为36 * 495= 396 * 45=17280


类似这样的巧合可能还有很多,比如27 * 594=297 * 54。


       假设a b c d e代表1~9不同的五个数字(注意是各不相同的数字,且不含0),能满足


这样的格式的式子总共有多少种?


public class 马虎的算式 {
    public static void main(String[] args) {
        int count=0;
        for (int a = 1; a <= 9; a++) {
            for (int b = 1; b <= 9; b++) { //每次for循环前要判断前面是否有相等元素
                if (a != b) for (int c = 1; c <= 9; c++) {
                    if (b != c && a != c) for (int d = 1; d <= 9; d++) {
                        if (a != d && b != d && c != d) for (int e = 1; e <= 9; e++) {
                            if (a != e && b != e && c != e && d != e) {
                                if ((a * 10 + b) * (c * 100 + d * 10 + e) == (a * 100 + d * 10 + b) * (c * 10 + e)) {
                                        count++;
                                }
                            }
                        }
                    }
                }
            }
        }
        System.out.println(count);//答案为142
    }
}

      🔑解析:这是道非常经典的枚举问题,很多人可能会觉得5个for循环这复杂度也太高了吧,但其实每个循环都是常数级,即使放到平时的刷题平台也不会超时。枚举类型的题目,需要大家答案的去实现,枚举当然就是想方设法去列出所有的情况,再判断是否符合题意。蓝桥杯对这种题型是钟爱有加,就是因为大家平时在各种刷题平台对这种题遇到比较少,一下紧张,不敢大胆地实现自己的思路。      


🚀3.振兴中华(基础动规问题)


       题目:小明参加了学校的趣味运动会,其中的一个项目是:跳格子


       地上画着一些格子,每个格子里写一个字;如下图


       从我做起振


       我做起振兴


       做起振兴中


       起振兴中华


       比赛时从左上角的的"从"字开始,只能横向或纵向跳到相邻的格子里,但不能跳到对角的格子,要求跳到"华"字结束。要求跳过的路线刚好是"从我做起振兴中华"这句话,请问小明有几种可能的跳跃路线        


public class 振兴中华 {
    public static void main(String[] args) {
        int[][] arr=new int[4][5];//注意是四列五纵
        for (int i = 0; i < 5; i++) {
            arr[0][i]=1;
        }
        for (int i = 0; i < 4; i++) {
            arr[i][0]=1;
        }
        for (int i = 1; i < 4; i++) {
            for (int j = 1; j < 5; j++) {
                arr[i][j]=arr[i-1][j]+arr[i][j-1];//状态转移方程
            }
        }
        System.out.println(arr[3][4]);//35种
    }
}

      🔑解析:这是道很简单的动规问题,当然没学过动规的兄弟会觉得有点难。没学过动规的兄弟建议先从斐波那契数列开始学习动规。动规是蓝桥杯的高频考点之一,它出的动规可能会很难也可能会很简单,所以兄弟们对于简单的动规问题千万不能做错。


🚀4.猜字母(字符处理问题)


      题目:


       把abcd....s共19个字母组成的序列重复拼接106次,得到长度为2014的串。


       接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字符。


       得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。


思路1:采用字符串形式


public class 猜字母 {
    public static void main(String[] args) {
        StringBuilder a=new StringBuilder("abcdefghijklmnopqrs");
        //StringBuilder效率更高
        for (int i = 1; i <106 ; i++) {
            a.append("abcdefghijklmnopqrs");
        }
        //重复拼接获得子串
        while (a.length()>1){  
               int l=a.length()/2;
            if (a.length()%2!=0) {
                l++;
            }
            for (int i = 0; i <l; i++) {//注意这里是i++不是i+=2,因为待删除的数组下标在变化
                a.deleteCharAt(i);
            }
        }
        System.out.println(a);//q
    }
}

🔑解析:首先这里我们用的是StringBuider,因为它的效率是最高的。这里我们才用字符串的一个好处是它自带的delete操作可以帮助我们删除元素,但正因如此也是我们容易掉坑的地方。当我们删除一个元素后,后续的元素会马上排上来,导致我们本该删除的元素的下标变化,导致了删掉了错误的元素。但其实也是有规律的,每删除一个元素后,后续所有待删除的元素都向左移动一格。比如有个字符串abcde,按照要求我们需要删掉ace这三个,a的下标为0删除后,原字符串变为bcde,这时本来下标为2的c变成了1,这时我们删掉c后再下一个待删除的元素e下标变为2了。于是本来需要隔一个再删除,却由于下标动态变化就只需要让i++而不是i+=2了。这里只需要考虑到长度为奇数时需要比偶数多删一次的问题即可,最后删剩的字符就是q。


相关文章
|
算法
【蓝桥杯集训·每日一题】AcWing 3768. 字符串删减
文章目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴 双指针
57 0
|
编译器 测试技术 C++
听说三数之和是你梦碎的地方?Leetcode每日刷题(day1)(上)
听说三数之和是你梦碎的地方?Leetcode每日刷题(day1)
听说三数之和是你梦碎的地方?Leetcode每日刷题(day1)(上)
|
双11 C语言
【牛客刷题】/*开胃菜——简单四道编程题*/
【牛客刷题】/*开胃菜——简单四道编程题*/
166 0
|
索引
小试牛刀——牛客篇
小试牛刀——牛客篇
113 0
小试牛刀——牛客篇
算法刷题第五天(跑路人笔记)<双指针>
算法刷题第五天(跑路人笔记)<双指针>
算法刷题第五天(跑路人笔记)<双指针>
算法刷题第二天(跑路人笔记)<双指针>
算法刷题第二天(跑路人笔记)<双指针>
算法刷题第二天(跑路人笔记)<双指针>
刷题笔记(较难篇)(c实现)(跑路人笔记)---链表1
刷题笔记(较难篇)(c实现)(跑路人笔记)---链表1
刷题笔记(较难篇)(c实现)(跑路人笔记)---链表1