思路2:采用数组形式
public class 猜字母02 { public static void main(String[] args) { char[] a=new char[2014]; int index=0; for (int i = 0; i < 106; i++) { for (int j = 0; j < 19; j++) { a[index++]= (char) ('a'+j);//这里涉及到ascii表的字母转换 } } //采用数组形式存放 int len=2014; while (len!=1){ int k=0; for (int i = 1; i <len ; i+=2) { a[k++]=a[i]; } len=k; } System.out.println(a[0]);//q } }
🔑解析:用数组形式来做的话更好理解也不容易出错。把每次需要留下来的元素往前摆。用len来动态地保存这一段的长度,k是待插入的下标。每次需要保存的元素往前放,然后用len更新保留下来的数组长度,一次次往前移动,不要的元素放数组后面。最后循环结束后,数组的第一个元素就是我们剩下的元素q。
🚀5.立方变自身(简单枚举)
题目:观察下面的现象,某个数字的平方,按位累加仍然等于自身
1^3=1
8^3=512 5+1+2=8
17^3=4913 4+9+1+3=17
...
请你计算包括1,8,17在内,符合这个性质的正整数一共有多少个?
public class 立方自身 { public static void main(String[] args) { int count = 0; //其实到最多到100就可以了,也可以加大范围枚举,会发现答案不会变多 for (int i = 1; i < 100; i++) { if (sum((int) Math.pow(i, 3)) == i) { count++; } } System.out.println(count);//6 } public static int sum(int x){//获得数x各个位相加的返回值 int count=0; while(x>0){ count+=x%10; x=x/10; } return count; } }
🔑解析:这道题就是普通的枚举题目,它的枚举范围也很好确定。当到100的三次方时,数就已经很大了,即使再往后枚举也不会让答案增多。不过为了更好确定,我们也可以把i的范围拉大继续枚举,会发现答案仍然也只有6个。
🚀6.三羊献瑞(7个for循环枚举问题)
题目:
观察下面的加法算式:
祥 瑞 生 辉
+ 三 羊 献 瑞
————————————
三 羊 生 瑞 气
public class 三羊祥瑞 { public static void main(String[] args) { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (i!=j)for (int k = 0; k < 10; k++) { if (i!=k&&j!=k)for (int l = 0; l < 10; l++) { if (i!=l&&j!=l&&k!=l)for (int m = 0; m < 10; m++) { if (i!=m&&j!=m&&k!=m&&l!=m)for (int n = 0; n < 10; n++) { if (i!=n&&j!=n&&k!=n&&l!=n&&m!=n)for (int o = 0; o < 10; o++) { if (i!=o&&j!=o&&k!=o&&l!=o&&m!=o&&n!=o){ int x1=i*1000+j*100+k*10+l; int x2=m*1000+n*100+o*10+j; if (isOK(x1,x2,i,j,k,l,m,n,o)){ System.out.println(" "+x1); System.out.println(" "+x2); System.out.println(x1+x2); } } } } } } } } } } public static boolean isOK(int x1,int x2,int i,int j,int k,int l,int m,int n,int o){ int count=x1+x2; if (count<10000) return false;//如果加起来不是五位数可以直接返回false int a=count%10; if (a==i||a==j||a==k||a==l||a==m||a==n||a==o) return false; count=count/10; a=count%10; if (a!=j) return false; count=count/10; a=count%10; if (a!=k) return false; count=count/10; a=count%10; if (a!=n) return false; count=count/10; a=count%10; if (a!=m) return false; return true; } }
🔑解析:这是一道非常非常经典的蓝桥真题枚举问题。最直接最暴力的方法就直接去写七个for循环分别将祥瑞生辉三羊献七个字枚举出来,再写一个判断答案是否符合要求的方法。思路很简单,但是步骤写起来需要小心。但其实这里我想说的是这里其实是可以优化的,两个四位数相加得到一个五位数。那么这个这个五位数的万位只可能是1,也就是三字其实就是1,既然祥加三得进位,三又是1,那么祥肯定就只能是9,进而再可得羊是0。大家可以和上面我贴出的答案对比就能看出来。这样其实我们的循环就少了几层了,但蓝桥杯做出答案才是目的,即使是7个for循环,但其实都是常数级的循环,瞬间就可以枚举出结果。
🚀7.加法变乘法(插乘枚举)
题目:
public class 加法变乘法 { public static void main(String[] args) { for (int i = 1; i <= 46; i++) { for (int j = i + 2; j <= 48; j++) { int count = i * (i + 1) + j * (j + 1);//一定要记得加括号 for (int k = 1; k <= 49; k++) {//将其余的数相加 if (k != i && k != i + 1 && k != j && k != j + 1) {//判断k不是我们前面已经用来相乘的数 count += k; //将剩余的数加起来 } } if (count == 2015) { System.out.println(i);//得到10 16 } } } } }
🔑解析:这道题也是经典的插入乘法的枚举问题。比较难处理的是如何进行相加和放乘号的位置。我们需要通过两个循环去模拟左右乘号的放入问题,外循环遍历左括号可能的位置,内循环遍历右括号可能的位置。因为乘号不可以相邻,所以左括号可能的位置是1的后面到46的后面,右括号每次起始的位置是i+2,最多可以到达48的后面。然后将第一个乘号的乘积加上第二个乘号的乘积得到count,然后遍历加上剩余的元素最后判断值是否是我们的2015。最后得到的输出有10和16,10是题目已经给过的答案,所以另外一个答案就16。
🍋3.蓝桥典型枚举问题总结和做题经验
以上我抽选的都是蓝桥杯较容易拿分的枚举填空题,这是我们拿分的关键,也是最容易拿分的题目。因为枚举只要你不着急,大胆去尝试和猜想,耐心的考虑到全部的情况,就一定可以算出答案。也不用去想着怎么去优化代码,只要能得到答案,就去尝试。当然得到答案后也一定要去验证一下,代码的细节也要把握好,否则很容易得到错误答案。最最主要的,还是要多加练习,包括以上的题目和以及视频资源我都为大家准备好了