🚀1.入场须知
本次蓝桥真题章节,选取的主要是全排列枚举问题,主要利用的是回溯算法来实现全排列,旨在让大家了解回溯算法和全排列对于征战蓝桥杯来说有多重要。因为蓝桥杯的枚举的量非常大,大家学习了本章的题目就能感觉到。
🚩2.征战蓝桥,力进国赛
👑 1.饮料换购
饮料厂举办一次促销优惠活动,乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。请你计算一下,如果小明不浪费瓶盖,尽可能地参加活动,那么,对于他初始买入的n瓶饮料最后他一共能喝到多少瓶饮料?
输入:一个整数n,表示开始购买的饮料数量(0<n<10000)
输出:一个整数,表示实际得到的饮料数
看到这道题不知道大家有没有想到冰红茶呢(童年回忆),这是一道往年的编程大题,还是非常简单的,根本没用到什么算法,最主要的是大家别忘记加上它最开始买的n瓶。
public static void main(String[] args) { //输入 Scanner sc = new Scanner(System.in); int n=sc.nextInt(); System.out.println(test(n)); } public static int test(int n){ //一开始买的n瓶先加入进count,count为最终获得的瓶数 int count=n; //当瓶盖数量小于3就结束了 while(n>=3){ n-=3; count++; n++; } return count; }
👑 2.牌型种数
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王,共52张),均匀发给4个人,每个人13张
这时,小明脑子里突然想到一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
这种题只能去穷举暴力遍历所有情况,想完成这个任务,只能使用回溯的方法去搜索所有的方法,而且因为是不分花色,每张牌都有相同的四张,所以我们还需要去重,因为有可能模拟到的情况有重复的。这题的计算量比较大,放在编译器上跑都需要十多秒才能出结果。不会回溯的同学一定要先去学习回溯,对于蓝桥杯来说非常的重要,因为需要枚举的情况可能性太多,只能通过回溯去搜索。
public class 牌型种数 { //用来存储52张牌 static int[] nums=new int[52]; //用来存储13张牌 static List<Integer> list=new ArrayList<>(); //统计所有的情况 static long ans=0L; public static void main(String[] args) { int p=0; for (int i = 1; i <= 13; i++) { nums[p++]=i; nums[p++]=i; nums[p++]=i; nums[p++]=i; } dfs(0); System.out.println(ans);//输出答案为3598180 } public static void dfs(int start){ if (list.size()==13){ ans++; } for (int i = start; i < nums.length; i++) { //树层去重 if (i>start&&nums[i]==nums[i-1]){ continue; } list.add(nums[i]); //递归 dfs(i+1); //回溯 list.remove(list.size()-1); } } }
👑 3.煤球数目
有一堆煤球,堆成三角棱锥体。具体:
第一层放1个,第二层3个,第三层6个,第四层10个,.............如果一共有100层,共有多少个煤球?
题目还是比较简单的,我们找出相加的规律即可。每次第i层,是在i-1层的基础上加上i个煤球。由此我们可以写出代码。用count来记录总和,用pre记录上一层的个数。
public class 煤球数目 { public static void main(String[] args) { //第一层总数 long count=1; //记录上一层(因为从第二层开始,所以pre开始记录的数是第一层的煤球数) int pre=1; //从第二层开始 for (int i=2;i<=100;i++){ //记录第i层多少个 pre+=i; //总数加上第i层 count+=pre; } System.out.println(count); } }
👑 4.生日蜡烛
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
这道题也是比较基础的题目,我们从1开始遍历,每次往后加即可,如果能恰好加到236,说明就是这个数,如果超过236说明就不是。继续下一个数的累加,直到找到答案。
public static void main(String[] args) { for (int i=1;i<=100;i++){ int count=0; int x=i; while(true){ //找到答案,输出 if(count==236){ System.out.println(i);//输出26,答案26岁 break; //说明不是这个数,跳出循环 }else if (count>236){ break; }else{ //继续累加 count+=x; x++; } } } }