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

本文总结了作者在蓝桥杯编程练习中的经验教训,包括序列求和、斐波那契数列、查找正数及十六进制转八进制等问题的解决方法,并详细解析了代码实现过程。

  偷懒几天又回来啦~~自上一篇微博已经三天了,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

 

转载于:https://www.cnblogs.com/ShallByeBye/p/8439846.html

<think>好的,我现在需要帮助用户了解如何备考蓝桥杯C++ B组的省等奖,并提供相关的经验和解题技巧。首先,我得回忆蓝桥杯的考试结构和重点。根据用户提供的引用内容,蓝桥杯省赛常考时间处理、日期计算、平闰年判断等,比如第十届的题目就涉及这些知识点[^2]。因此,备考时需要特别关注这些高频考点。 接下来,用户可能需要的不仅仅是知识点,还有如何高效备考的策略。根据引用[1],推荐参加些小比赛来练习,比如蓝桥杯官方的竞赛和LeetCode周赛,这些能帮助培养时间紧迫感。所以,我应该建议用户多参与模拟赛和在线竞赛,提升实战能力。 然后,我需要分步骤组织回答。首先梳理考试大纲,明确重点;接着推荐学习资料和练习平台;再讲解解题技巧,比如时间处理题的解法;最后提到模拟考试的重要性。这样结构清晰,用户能逐步跟进。 关于解题技巧部分,必须具体。例如日期处理题,可以举例如何判断闰年,计算星期几的方法,使用蔡勒公式或模拟法。同时,注意代码实现的效率,避免超时。这里可能需要给出代码示例,比如判断闰年的函数,并确保用$$...$$格式包裹独立公式,如判断闰年的条件: $$ \text{闰年条件:年份能被4整除但不能被100整除,或能被400整除} $$ 此外,动态规划和搜索算法也是常考内容,需强调它们的掌握。比如,DFS/BFS的模板,动态规划的状态转移方程设计。 还要注意用户提到的资料获取,比如推荐官方练习系统和《算法竞赛入门经典》等书籍。同时提醒时间管理,省赛通常4小时10题,合理分配时间,先易后难。 最后,模拟考试的重要性,通过历年真题熟悉题型,找出薄弱环节。引用中的蓝桥杯官方比赛和LeetCode竞赛都是很好的练习途径[^1][^2]。 检查是否需要覆盖所有用户可能的问题,比如备考资料、技巧、常见题型。确保回答涵盖这些方面,结构清晰,每个部分有具体建议和例子。同时,添加相关问题,如如何优化日期处理代码,动态规划的应用场景等,符合用户要求生成相关问题。 总结,回答需要分点明确,结合引用内容,提供实用建议和示例,确保用户能系统备考,提升通过几率。</think>### 蓝桥杯 C++ B组 省 备考经验及解题技巧 #### 1. **明确考试大纲与高频考点** - **基础算法与数据结构**:排序、查找、递归、动态规划、贪心算法、DFS/BFS等是必考内容,需熟练掌握模板。 - **数学与逻辑题**:日期计算(平闰年判断、星期推算)、数论(最大公约数、质因数分解)、几何问题等常出现在省赛中。 - **模拟与字符串处理**:复杂场景的模拟题(如游戏规则实现)、字符串操作(分割、匹配)需注意代码细节。 **示例:日期处理题** 判断闰年的条件: $$ \text{闰年条件:年份能被4整除但不能被100整除,或能被400整除} $$ 计算两个日期间的天数时,需逐月累加并处理闰年。 #### 2. **学习资源推荐** - **官方资源**:蓝桥杯官网的历年真题和模拟题(含题解)是核心资料[^1]。 - **书籍**:《算法竞赛入门经典》(刘汝佳)适合打基础,《算法笔记》提供实战技巧。 - **在线平台**: - **洛谷**:分类训练题库(如“普及/提高组”题目)。 - **AcWing**:蓝桥杯专项课程(含C++代码模板)。 - **LeetCode**:周赛/双周赛提升编码速度和调试能力。 #### 3. **解题技巧与实战策略** - **时间处理题**: 使用**蔡勒公式**快速计算星期几: $$ w = \left( y + \left\lfloor \frac{y}{4} \right\rfloor + \left\lfloor \frac{c}{4} \right\rfloor - 2c + \left\lfloor \frac{13(m+1)}{5} \right\rfloor + d - 1 \right) \mod 7 $$ 其中,$c$ 为世纪数,$y$ 为年份后两位,$m$ 为月份(3-14,1月和2月视为上年的13、14月)。 - **动态规划题**: 典型问题如背包问题、最长公共子序列。设计状态转移方程时,优先考虑**空间优化**(如滚动数组)。 - **搜索与剪枝**: DFS/BFS需结合剪枝,例如“状态缓存”(记忆化搜索)或“可行性预判”(提前终止无效分支)。 **代码片段示例(日期累加)** ```cpp bool is_leap(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } ``` #### 4. **时间管理与调试技巧** - **省赛时间分配**:4小时内完成10题,建议简单题(30分钟内)、中等题(45分钟)、难题(剩余时间+放弃策略)。 - **调试方法**: - 对边界条件(如闰年2月29日、数组越界)单独测试。 - 使用`printf`中间输出或断点调试(如Dev-C++调试器)。 #### 5. **模拟考试与复盘** - 每周至少完成1套历年真题,限时训练后对照题解分析错误原因。 - **高频错题整理**:例如日期题中“跨年计算错误”或动态规划的“状态初始化遗漏”。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值