你好呀,我是灰小猿,一个超会写bug的程序猿!
欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!
标题:猜字母
把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串,
接下来删除第一个字母,(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作,如此下去,最后只剩下一个字母,请写出该字母。
答案是一个小写字母,请通过浏览器提交答案,不要填写任何多余的内容。
解题思路:
根据题意我们知道,题目中的要求是将长度为2014的串中的奇数位循环去掉,最后只剩下一个字母并求得该字母的过程,很多人在看到这样一个问题的时候第一个想到的是使用列表的形式来存放这长度为2014的串,因为这样可以使用remove方法将奇数位上的字符删除,由此循环下去,最后只剩下一个字符,这种方法看似可行,但是在实际的操作中会发现其实不然,原因是因为在每次使用remove方法删除字符之后,列表的长度就会减少一位,这样在删除下一个的时候,其实删除的已经不是之前的奇数位上的字符了,这就不能保证每次循环时串的长度和奇数位上的字符是固定的。
因此想到这里,我们可以使用数组来代替,虽然数组无法直接将奇数位上的字符删除,但是却可以将偶数位上的字符前移,最后将所有的偶数位移到最前面,假设每次移动k个偶数位的字符,那么在下一次移动时,就可以将数组的前k位作为新数组,然后重复第一步的操作。直至最后k=1,也就是数组中只移动一个偶数位时,该偶数位上的字符就是最终答案是字母q。
答案源码:
public class Year2014_Bt3 { public static void main(String[] args) { char[] c = new char[2014]; //存放所有的字母 int index = 0; //标记数组中元素下标 //循环106次,将前19个字母存放到数组中 for (int i = 1; i <= 106; i++) { for (int j = 0; j < 19; j++) { c[index++] = (char) ('a' + j); } } int len = 2014; //当有效数组长度不是1时,让偶数位前移 while (len!=1) { int k=0; //将偶数位从0开始向后赋给数组 for (int i = 1; i < len; i+=2) { c[k++] = c[i]; } len = k; //记录每次剩余的偶数位,也是下一次有效数组的长度 } System.out.println(c[0]); } }
输出样例: