蓝桥杯☆难度题目(6,7题)

来源:互联网 发布:英国可以用淘宝吗 编辑:程序博客网 时间:2024/06/01 09:06
1.密码发生器
    在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,容易被破解,不安全;如果设置不好记的密码,又担心自己也会忘记;如果写在纸上,担心纸张被别人发现或弄丢了...
    这个程序的任务就是把一串拼音字母转换为6位数字(密码)。我们可以使用任何好记的拼音串(比如名字,王喜明,就写:wangximing)作为输入,程序输出6位数字。

    变换的过程如下:
    第一步. 把字符串6个一组折叠起来,比如wangximing则变为:
    wangxi
    ming
    第二步. 把所有垂直在同一个位置的字符的ascii码值相加,得出6个数字,如上面的例子,则得出:
    228 202 220 206 120 105
    第三步. 再把每个数字“缩位”处理:就是把每个位的数字相加,得出的数字如果不是一位数字,就再缩位,直到变成一位数字为止。例如: 228 => 2+2+8=12 => 1+2=3

    上面的数字缩位后变为:344836, 这就是程序最终的输出结果!

    要求程序从标准输入接收数据,在标准输出上输出结果。
    输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行字符串,就是等待变换的字符串。
    输出格式为:n行变换后的6位密码。

    例如,输入:
5
zhangfeng
wangximing
jiujingfazi
woaibeijingtiananmen
haohaoxuexi
    则输出:
772243
344836
297332
716652
875843

题目分析:
1.做一个for,循环输入名字,这里要注意的是从int到字符串用next就行,不能用Line,否则会出现读取换行符的情况。而处理输入多个一块处理的方式,其实直接一起放进去就可以了。
2.做第一个方法,新建6位int型数组,将字符char进行对号放置(这个时候发生转换),用%6的方式(放在0-5之间)
3.做另一个方法,循环对整形进行相加压缩,计算各位相加的值。为了处理相加后还是两位数以上的,使用递归处理。

...  for (int i = 0; i < name.length; i++) {
          name[i]=input.next();
     }
     for (int i = 0; i < name.length; i++) {
          cut(name[i]);
     }


public static void cut(String st) { 
     int[] bianHao=new int[6];
     for (int i = 0; i < st.length(); i++) {
          bianHao[i%6]+=st.charAt(i);
     }
     for (int i = 0; i < bianHao.length; i++) {
          System.out.print(show(bianHao[i]));
     }...


public static int show(int num) {
     if(num<10){
          return num;
     }
     int temp=0;
     while(num>0){
          temp+=num%10;
          num=num/10;
     }
     return show(temp);
}

要点注意:
1.调用递归的式子尽可能避开数组,用整形进行调用,特别是在这道题中,他return的数需要进行再一次压缩。
2.回车问题只要把打印提取出来就可以解决,这个地方用存入数组解决


2.比酒量
    有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。
    等船长醒来,发现海盗船搁浅了。他在航海日志中写到:“......昨天,我正好喝了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”
    请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。
    如果有多个可能的答案,请列出所有答案,每个答案占一行。
    格式是:人数,人数,...
    例如,有一种可能是:20,5,4,2,0

题目分析:
1.用循环确定每轮倒下的人数
2.条件将分数和为1转化为乘积总值为800

        ...       for (int l = 1; l <=20-i-j-k; l++) {

                        int all=i*j*k*l;
                        if(all/i+all/j+all/k+all/l==all){
                             System.out.println(i+" "+j+" "+k+" "+l+" 0");
                        }
                   }    ...

3.奇怪的分式
上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:
1/4 乘以 8/5
小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)
老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!
对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?
请写出所有不同算式的个数(包括题中举例的)。
显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。
但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!

题目分析:
1.注意看题意,计数是从1开始的
2.要求分子分母不相同,只需判断一对就行

... if(i!=j&&i*k*(j*10+l)==j*l*(i*10+k)){
        count++;
        System.out.println(i+"/"+j+"*"+k+"/"+l+"="+(i*10+k)+"/"+(j*10+l));
    }...

答案是:14

4.神奇算式
由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。
比如:
210 x 6 = 1260
8 x 473 = 3784
27 x 81 = 2187
都符合要求。
如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。

题目分析:
1.这里需要解决三个问题:
          a.数字互不相同     b.左右数字相同     c.交换律不算
2.数字互不相同用存入数组解决
3.左右数字相同也用存入数组,进行比较解决
4.交换律排除用分离法,或者是半分离法:
          a.分离法,分成1&3和2&2(需要判断前面小于后面)     b.半分离法:第一部分与第二部分,只是第二部分一定大于第一部分

要点注意:
1.添加限制条件:数字后面大于前面
2.比较相等是值与两个乘数比较,而不是两个乘数之间进行比较
3.第二部分的范围是从2位到3位,而不仅仅是3位

...  for (int i = 1; i < 100; i++) {
          for(int j=10; j<1000; j++){
               if(tong(i,j)&&zhi(i,j,i*j)&&i<j&&i*j>1000&&i*j<10000){
                   all++;
                   System.out.println(i+"*"+j+"="+i*j);
              }
          }
     }...

...  while(i>0){
          num1[i%10]=1;
          i=i/10;
     }
     while(j>0){
          num1[j%10]=1;
          j=j/10;
     }
     while(k>0){
          num2[k%10]=1;
          k=k/10;
     }
     for (int l = 0; l < num2.length; l++) {
          if(num1[l]!=num2[l]){
              return false;
          }
     }
     return true;


     int[] arr=new int[10];
     int count=0;
     while(i>0){
          arr[i%10]=1;
          i=i/10;
          count++;
     }
     while(j>0){
          arr[j%10]=1;
          j=j/10;
          count++;
     }
     int temp=0;
     for (int k = 0; k < arr.length; k++) {
          temp+=arr[k];
     }
     if(temp!=count){
          return false;
     }
     return true;
}
最后答案是:12
6 * 201 = 1206
6 * 210 = 1260
21 * 60 = 1260
15 * 93 = 1395
35 * 41 = 1435
3 * 501 = 1503
3 * 510 = 1530
30 * 51 = 1530
21 * 87 = 1827
27 * 81 = 2187
9 * 351 = 3159
8 * 473 = 3784

5.猜字母
把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。

题目分析:
1.设置3000的数组脚标,用数字代表字母
2.做无限循环(>1),将偶数位存到前面
3.输出最后1位数
这里有一个要点需要注意:新建数组的时候多加1,这样数组和数字才会对应

...  while(num>1){
          num=num/2;
          for (int i = 1; i <=num ; i++) {
              arr[i]=arr[i]*2;
          }
     }
     System.out.println(arr[1]%24);   ...

答案为1024   %24=16,第16个字母为p

6.平方怪圈
如果把一个正整数的每一位都平方后再求和,得到一个新的正整数。
对新产生的正整数再做同样的处理。
如此一来,你会发现,不管开始取的是什么数字,
最终如果不是落入1,就是落入同一个循环圈。

请写出这个循环圈中最大的那个数字。
请填写该最大数字。

题目分析:
1.输出100个得数,用来看循环规律
2.每次算出平方和的数,赋值给n并且输出来

... for (int i = 0; i < 100; i++) {
          int newNum=0;
          while(temp>0){
              newNum+=(temp%10)*(temp%10);
              temp=temp/10;
          }
          temp=newNum;
          System.out.println(newNum);
     }...
这里记得将新求得的数字存为下一个被平方和的数字
不管定义的是什么数字,循环节都将是以下这串数字:
4     16     37     58     89     145     42     20

7.放麦子
    你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第1个棋盘格放1粒麦子,在第2个棋盘格放2粒麦子,在第3个棋盘格放4粒麦子,在第4个棋盘格放8粒麦子,......后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有64格)。
    国王以为他只是想要一袋麦子而已,哈哈大笑。
    当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!
    请你借助计算机准确地计算,到底需要多少粒麦子。

题目分析:
1.这道题用到的是BigInteger的特性
2.用pow求次方
3.利用 当前次方数 为 前面次方和+1的规律,推测出第64位总和的值

     BigInteger count=new BigInteger("2");
     System.out.println(count.pow(64).subtract(new BigInteger("1")));

8.马虎的算式
    小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
    有一次,老师出的题目是:36 x 495 = ?
    他却给抄成了:396 x 45 = ?
    但结果却很戏剧性,他的答案竟然是对的!!
    因为 36 * 495 = 396 * 45 = 17820
    类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54
    假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
    能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?

请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。

题目分析:
1.使用暴力循环+合成的方法
2.注意要点:每个数都不相同,所以每个for都要进行不同判断
                  ...
                    for (int d = 1; d < 10; d++) {
                        if(d==a||d==b||d==c){
                             continue;
                        }
                        for (int e = 1; e < 10; e++) {
                             if(e==a||e==b||e==c||e==d){
                                  continue;
                             }
                             if((a*10+b)*(c*100+d*10+e)==(a*100+d*10+b)*(c*10+e)){
                                  count++;
                             }...
答案是142
9.三羊献瑞
观察下面的加法算式:

       祥 瑞 生 辉
  +   三 羊 献 瑞
-------------------
   三 羊 生 瑞 气

其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一)

题目分析:
1.用8个for暴力破解,每一层判断与其他数字不相同
2.注意第一位应该从1开始,而不是0

...
                                      for (int p = 0; p < 10; p++) {
                                           if(p==i||p==j||p==k||p==l||p==m||p==n||p==o){
                                                continue;
                                           }
                                           int a=n*1000+l*100+k*10+o;
                                           int b=i*1000+j*100+p*10+l;
                                           int c=i*10000+j*1000+k*100+l*10+m;
                                           if(a+b==c){       ...
10.凑算式

         B       DEF
A + --- + --------- = 10
        C        GHI
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?

题目分析:
1.使用暴力合成法
2.暴力需要处理数互不相同的问题
3.注意:为了解决分数结果被消尾,需要先看看分子%分母是0才通过
                             ...         for (int c9 = 1; c9 < 10; c9++) {
                                                if(c9==c1||c9==c2||c9==c3||c9==c4||c9==c5||c9==c6||c9==c7||c9==c8){
                                                     continue;
                                                }
                                               int one=c4*100+c5*10+c6;
                                               int two=c7*100+c8*10+c9;
                                               int fenshu=(c3*one+c2*two);
                                                if(fenshu%(c3*two)==0){  //判断整除
                                                     if(c1+fenshu/(c3*two)==10){   //能被整除再整除
                                                          count++;
                                                     }
                                                }
                                           }...
答案是:29
注意事项:要先判断分数的结果符合为整数,才进行下一步的加法运算,否则可能会导致精度丢失运算出错

11.汉诺塔
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上(可以借助第三根柱子做缓冲)。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
如图【1.jpg】是现代“山寨”版的该玩具。64个圆盘太多了,所以减为7个,金刚石和黄金都以木头代替了......但道理是相同的。
据说完成大梵天的命令需要太多的移动次数,以至被认为完成之时就是世界末日!
你的任务是精确计算出到底需要移动多少次。
很明显,如果只有2个圆盘,需要移动3次。
圆盘数为3,则需要移动7次。
那么64个呢?

题目分析:
1.把上面n-1个盘子 从A,借助C,移动到B
2.把最下面的盘子从A移动到C
3.把B上n-1从B借助A,移动到C

public static void main(String[] args) {
     hanoi(3,"A","B","C");
}

public static void hanoi(int num, String start, String pro, String end) {
     if(num==1){
          System.out.println(start+"-->"+end);
          return;
     }
     hanoi(num-1,start,end,pro);
     hanoi(1,start,"",end);
     hanoi(num-1,pro,start,end);
}

只求结果的话:直接利用公式:2n次方-1
注意:递归函数只需要反应执行的过程:a.把第一个以上的搬开     b.把最后一个放到结尾位置     c.把除最后一个放到结尾位置
而他处理的工作就是把最后一个放置到结尾的动作显示出来。所以最后一重到这推就是:我输出最后一个的动作,该动作来自于当只有两个的时候,上面那个被搬开,把下面那个显示出来。上面那个怎么显示呢?当显示完最下的一个后,其余的一个就搬上去。怎么只剩两个呢,因为上面的第三个搬回了A的位置,如此循环一直到结束。
0 0
原创粉丝点击