码迷,mamicode.com
首页 > 其他好文 > 详细

蓝桥杯练习系统错题总结—(一)

时间:2018-02-10 22:36:01      阅读:337      评论:0      收藏:0      [点我收藏+]

标签:运算   二进制   class   中间   switch   post   pre   c语言   序列   

  偷懒几天又回来啦~~自上一篇微博已经三天了,2.7按照最新计划做了蓝桥杯练习系统的10题,2.8小年+2.9两天给自己放了个假。今天又开始每日十题了!!

  决定 今天这篇来总结一下这两天做题遇到的问题吧。大部分都是一些数据范围考虑的不到啊之类的,下面开始啦!

  第一题:序列求和。其实这道题已经是第二次做了。因为之前做错过(for循环1-n相加求和)所以这次注意到了这个范围的问题 数据规模与约定 1 <= n <= 1,000,000,000。因为是入门题,所以他给了提示,如下

说明:请注意这里的数据规模。

本题直接的想法是直接使用一个循环来累加,然而,当数据规模很大时,这种“暴力”的方法往往会导致超时。此时你需要想想其他方法。你可以试一试,如果使用1000000000作为你的程序的输入,你的程序是不是能在规定的上面规定的时限内运行出来。

本题另一个要值得注意的地方是答案的大小不在你的语言默认的整型(int)范围内,如果使用整型来保存结果,会导致结果错误。

如果你使用C++或C语言而且准备使用printf输出结果,则你的格式字符串应该写成%I64d以输出long long类型的整数。

技术分享图片

这是第一次的代码,没用循环,用的数学公式1+2+3+....+n=(1+n)*n/2  ps:这个题第一次做的时候我都忘了这个式子了,对不起数学老师。这个代码不能过所有的数据,当后面大数据的时候就过不去了,输入1,000,000,000然后输出了n,是可以的。所以一开始觉得不在int n,然后看了之前写的代码,问题还真的是在int啊。虽然n最大1000000000在int范围内,但是要用long保存结果我的理解是如果你中间运算用了int,可能中间运算过程会有强制类型转换,导致出错 。就像n*(n+1) 1000000000*1000000001肯定就超了int,但是int*int还是int啊,所以这里保存数据就会有问题了。

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         //1+2+3+....+n=(1+n)*n/2
 6         Scanner sc=new Scanner(System.in);
 7         int n=sc.nextInt();
 8         long sum=(1+n)*n/2;
 9         System.out.println(sum);
10     }
11 
12 }

这一版是改过之后的:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         //1+2+3+....+n=(1+n)*n/2
 6         //虽然n最大1000000000在int范围内,但是要用long保存结果,我的理解是如果你中间运算用了int
 7         //可能中间运算过程会有强制类型转换,导致出错        
 8         Scanner sc=new Scanner(System.in);
 9         long n=sc.nextLong();
10         long sum=(1+n)*n/2;
11         System.out.println(sum);
12     }
13 }

第二题:又是斐波那契数列,怎么感觉最近这个总出问题,哎呀,过不去的坎了。

技术分享图片

哎呀,这个题也是做过的。然后第一次做的时候就是简单的for循环,是的又是for循环,然后再%10007,然后是超时的。然后我记得之前做的时候说是可以这样:(A+B)%a=(A%a)+(B%a)节省时间

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         Scanner sc=new Scanner(System.in);
 7         long n=sc.nextLong();
 8         long []f=new long[(int) (n+1)];
 9         for(int i=1;i<=n;i++){
10             if(i==1||i==2){
11                 f[i]=1%10007;
12             }
13             else{
14                 f[i]=f[i-1]%10007+f[i-2]%10007;
15             }
16         }
17         System.out.println(f[(int) n]);
18     }
19 
20 }

然后这样做了提交看,不对!!!我又看了测试数据,原来有的余数都>10007了,然后把刚刚的式子改成这样(A+B)%a=((A%a)+(B%a))%a就对了。真的有时候不知道是自己不仔细呢还是真的没考虑到思路不对,哎,头疼。

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         Scanner sc=new Scanner(System.in);
 7         int n=sc.nextInt();
 8 //        System.out.println(n);
 9         long []f=new long[(n+1)];
10         for(int i=1;i<=n;i++){
11             if(i==1||i==2){
12                 f[i]=1%10007;
13             }
14             else{
15                 f[i]=f[i-1]%10007+f[i-2]%10007;
16             }
17         }
18         System.out.println(f[n]%10007);
19     }
20 }

第三题:查找正数

技术分享图片

这个因为我之前刚写了一篇关于ArrayList的文章,所以印象很深刻,就觉得用ArrayList合适。这是第一遍的代码

 1 import java.util.ArrayList;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5     public static void main(String[] args) {
 6         Scanner sc=new Scanner(System.in);
 7         int n=sc.nextInt();
 8         ArrayList<Integer> list=new ArrayList<Integer>();
 9         for(int i=0;i<n;i++){
10             list.add(sc.nextInt());
11         }
12         int search=sc.nextInt();
13         int result=list.indexOf(search)+1;
14         System.out.println(result);
15     }
16 
17 }

用的indexof方法查找 search的位置。因为说从1开始,所以我用了+1.然后提交,发现有问题,当你数列中没有这个数的时候,他会输出0(-1+1),显然是不对的,应该是-1才对(题目中给出了)下面是改正之后的代码:

 1 import java.util.ArrayList;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5     public static void main(String[] args) {
 6         Scanner sc=new Scanner(System.in);
 7         int n=sc.nextInt();
 8         ArrayList<Integer> list=new ArrayList<Integer>();
 9         for(int i=0;i<n;i++){
10             list.add(sc.nextInt());
11         }
12         int search=sc.nextInt();
13         int result=list.indexOf(search)+1;
14         if(result<1){
15             System.out.println(-1);
16         }else{
17             System.out.println(result);
18         }        
19     }
20 }

这样就ok了。还是写完运行的时候自己在多想想几种情况测试一下啊gg

第四题:十六进制转八进制,也是我唯一觉得有意义来分析、来写的题。如果只是简单的进制转换那么java有很多自带的方法很好用根本不需要自己写。但是这个题稍有不同。

技术分享图片

这是第一次写的错误的代码:用的Integer.toString把16进制转8进制他显示的是 运行错误,我一开始以为是Main类名啊,或者语言选错了。然后看测试数据试了一下不是这个问题,

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         Scanner sc=new Scanner(System.in);
 7         int n=sc.nextInt();
 8         while(sc.hasNext()){
 9             String s=sc.next();
10             int a=Integer.parseInt(s,16);
11             System.out.println(Integer.toString(a,8));
12         }
13         
14     }
15 
16 }

这是input1的数据截图,看了就知道多可怕了。而且这只是其中的一个片段,巨长巨长的数据段。然后就觉得应该是数据范围的问题了。

技术分享图片

我换了biginteger但是这个转换又找不到对应的函数了,所以有根据他的提示,把16进制转为2进制,然后三位一转成8进制,开始写代码。超长预警。

思路就是上面的这句话啦。然后16进制转为2进制自己建方法写,具体就是0->0000 1->0001 2->0010....这样一一对应。然后开始写二进制转成8进制。但是这里有一个注意点就是 他是三位一转(2的3次方=8),如果不够从最前面+0.所以需要长度对3求余  余1+00 余2+0.然后也是采用一一列举的方法 把2进制和8进制数字对应起来。

 1 mport java.math.BigInteger;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5     public static String toBinary(String s){
 6         StringBuffer stb=new StringBuffer();
 7         for(int i=0;i<s.length();i++){
 8             switch(s.charAt(i)){
 9             case ‘0‘:stb.append("0000");break;
10             case ‘1‘: stb.append("0001"); break;
11             case ‘2‘: stb.append("0010");break;
12             case ‘3‘: stb.append("0011"); break;
13             case ‘4‘: stb.append("0100"); break;
14             case ‘5‘: stb.append("0101"); break;
15             case ‘6‘: stb.append("0110"); break;
16             case ‘7‘: stb.append("0111"); break;
17             case ‘8‘: stb.append("1000"); break;
18             case ‘9‘: stb.append("1001"); break;
19             case ‘A‘: stb.append("1010"); break;
20             case ‘B‘: stb.append("1011"); break;
21             case ‘C‘: stb.append("1100"); break;
22             case ‘D‘: stb.append("1101"); break;
23             case ‘E‘: stb.append("1110"); break;
24             case ‘F‘: stb.append("1111"); break;
25             default: break;
26             }
27         }
28         return stb.toString();
29     }
30     public static String toOctal(String strBinary) {
31         int len=strBinary.length();
32         int k;
33         StringBuffer stb=new StringBuffer();
34         if(strBinary.substring(0, 3).equals("000")) k=3;
35         else k=0;
36         for(int i=k;i<len-2;i+=3){
37             switch (strBinary.substring(i, i+3)) {
38             case "000":stb.append("0");break;
39             case "001":stb.append("1");break;
40             case "010":stb.append("2");break;
41             case "011":stb.append("3");break;
42             case "100":stb.append("4");break;
43             case "101":stb.append("5");break;
44             case "110":stb.append("6");break;
45             case "111":stb.append("7");break;
46             default:break;
47         }
48         }
49         return stb.toString();
50     }
51     public static void main(String[] args) {
52         Scanner sc=new Scanner(System.in);
53         int n=sc.nextInt();
54         while(sc.hasNext()){
55             String s=sc.next();
56             String strBinary=toBinary(s);
57             if(s.length()%3==1) strBinary="00"+strBinary;
58             if(s.length()%3==2) strBinary="0"+strBinary;
59             String strOctal=toOctal(strBinary);
60             System.out.println(strOctal);
61         }
62         
63     }
64 
65 }

就是这样了,其实还有个杨辉三角,第一天做的时候正好是最后一题很浮躁没看进去做了他的下一题,第二次做给忘了。所以一直没做,等过几天下次总结的时候一起吧。

好了,就这样,看电视去了,拜拜~~~Nice Day

 

蓝桥杯练习系统错题总结—(一)

标签:运算   二进制   class   中间   switch   post   pre   c语言   序列   

原文地址:https://www.cnblogs.com/ShallByeBye/p/8439846.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!