准备参加第十四届蓝桥杯,今天开始刷题目的第一天,下面是2020年第十一届C/C++ B组第一场蓝桥杯省赛真题,以下是我的做题目心得。
跑步训练
第一次写的代码失误点如下:第一个错误点是因为好久没有写代码,忘记判断对才能循环,算是失误。第二个点如果在现实中是对的,但是在代码里面会因为格式转换导致power/600变成0.这需要注意一下。
代码如下:
int main() {int power = 10000;int expend = -600;int recover = 300;int min = 0;while (power > 600) {power += expend;min++; if (power == 0) {break;}power += recover;min++;}if (power == 0) {cout<<min*60;}else {cout<<min*60+power/10;}return 0;
}
纪念日
本题目我是从1921年开始计算的,而且我把算闰年的部分分开了。
计算闰年的判断如下:普通闰年:公历年份是4的倍数且不是100的倍数为普通闰年(如2004、2020年就是闰年)。
世纪闰年:公历年份是整百数的,必须是400的倍数才是世界闰年(如2000是世纪闰年,1900不是世纪闰年)。
因为是填空题,我写的代码并不是很好看,只是用于计算。
最后代码如下:
#include<iostream>
using namespace std;
int main(){int year = 2020 - 1921;//年数 int m = (2020 - 1924) / 4 + 1;//闰年数 int day = year * 365 + m -22; //天数 cout<<day*24*60;
}
合并检测
本题目没有告诉我们A国的人数,这一开始就有点没有头绪,然后我们可以从感染率为1入手,毕竟代表人的数字不能是小数,那我就设A国总人数为100,这样简单也方便。那感染的人就只有一个。设试管的使用量为sum,可以得下面的试子:
A国人数可被k整除:sum=100/k+k
A国人数不能被k整除:sum=100/k+k+1
最后代码如下:
#include<iostream>
using namespace std;int main()
{int k = 0;int sum = 0x3f3f3f;//试管数量 for(int i = 1; i <= 100; i++){if(100%i==0){if(100/i+i<sum){sum=100/i+i;k = i;}}else{if(100/i+1+i<sum) {sum=100/i+1+i;k=i;}}}cout << k <<endl;return 0;
}
REPEAT程序
我们可以看看题目的对应方式,可以发现有点像for循环,其中REPEAT后面的数字就代表要循环的次数而且A=A+5循环了60次,说明它是最里面的命令行。
代码如下:
#include<iostream>
using namespace std;
int main() {int A = 0;for (int i = 0;i < 2;i ++) {A += 4;for (int j = 0;j < 5;j ++) {for (int k = 0;k < 6;k ++) {A += 5;}A += 7;}A += 8;} A += 9;cout << A <<endl;return 0;
}
矩阵
这个题目需要使用动态规划的知识,其中动态规划的知识可以分三步走:
第一步,定义一个数组元素的定义,我定义一个dp[i][j]的数组,i代表放在第一行的数字量,j代表第二行的数字量。
因为是2×1010的矩阵,所以每一行的最大数字量为1010.
第二步,找出数组元素之间的关系式:
将当前数放在第一行:dp[i][j] += dp[i - 1][j],将当前数放在第二行:dp[i][j] += dp[i][j - 1]
第三步,得找到一个初始值.比如在矩阵里面不放数字,也是一种方案,故dp[0][0]=1
最后代码如下:
#include<iostream>
using namespace std;
int dp[1011][1011];
int main() {dp[0][0]=1;for(int i = 0;i <= 1010;i ++) {for(int j = 0;j <= 1010;j ++) {if(i-1 >= j) {dp[i][j] += dp[i-1][j] % 2020;}if(j) {dp[i][j] += dp[i][j-1] % 2020; }}} cout<< dp[1010][1010] <<endl;return 0;
}
整除序列
这个题目使用while语句即可完成,而且最好不用存在数组里面,直接得答案后就输出
代码如下:
#include<iostream>
using namespace std;
int main() {int num; cin>>num;cout<<num << " ";while(num > 1) {num =num/2;cout<<num << " ";}return 0;
}
解码
这个题目只要会使用string库就可以解出来了
代码如下:
#include<iostream>
#include<string>
using namespace std;
int main () {string st;cin>>st;for(int i = 0;i < st.length();i ++) {if (st[i] > 48 && st[i] < 58) {for(int j = 1;j < st[i]-48;j ++) {cout<<st[i-1]; } }else {cout<<st[i];} } return 0;
}
走方格
这个还是使用的是动态规划,加一个小的限制就是m和n不能同时为偶数,但是这个并不重要,我们直接分析,三步走。
第一步,定义一个数组。dp[i][j],带表它走到的位置需要花费的方案。
第二步,找出数组元素之间的关系式:dp[i][j]=dp[i-1][j]+dp[i][j-1]
第三步,找出初始值。因为它只能向右或者向下,这样的话可以初始以下两方面:
dp[0] [0….n-1] = 1; // 相当于最上面一行,只能一直往左走
dp[0…m-1] [0] = 1; // 相当于最左面一列,只能一直往下走
代码如下:
#include<iostream>
using namespace std;
int dp[31][31];
int count(int m,int n);
int main(){int m,n;cin>>m>>n;if(!(m % 2 |n % 2)) {cout<<0;}else {cout<<count(m,n);}return 0;
}
int count(int m,int n) {for(int i = 1;i <= n;i ++) {dp[i][1] = 1;}for(int j = 1;j <= m;j ++) {dp[1][j] = 1;}for(int i = 2;i <= n;i ++) {for(int j = 2;j <= m;j ++) {if(!(i % 2 |j % 2)) {continue;}dp[i][j] = dp[i-1][j] + dp [i][j-1]; }}return dp[n][m];
}
整数拼接
一开始想的是把数字变成字符串,后面拼接后再改成数字,但是这样太麻烦,我也不会,那我们可以求它的位数,用次方的方式来使他变成拼接的前半部分。思路清晰后代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int figure(int num); //求位数
int main() {int n,k;int count = 0;int num;cin>>n>>k;int a[n];for(int i = 0;i < n;i ++) {cin>>a[i];}for(int i = 0;i < n;i ++) {for(int j = 0;j < n;j ++) {if(i == j) {continue;}num = a[i]*pow(10,figure(a[j]))+a[j];//这样可以直接加在后面 if(num % k == 0) {count++;}}}cout<<count;return 0;
}
int figure(int num) {int n = 0;int m = 1;while(m) {m = num;m /= 10;n++;}return n;
}
网络分析
我看见这个题目需要使用的知识点是图的知识点,由于可以相互通讯,那就是无向连接,由于它是需要遍历的,那我们可以思考一下DFS与BFS算法相关知识。我使用邻接矩阵来存储。
代码如下:
#include<iostream>
#include<queue>
using namespace std;
int main() {int n,m,top;cin>>n>>m;queue<int> myqueue;int a[n][n];//邻接矩阵 int b[n][n];for (int i = 0;i < n;i ++) {for (int j = 0;j < n;j ++) {a[i][j] = 0; } }for (int i = 0;i < n;i ++) {for (int j = 0;j < n;j ++) {b[i][j] = 0; } }int m1,m2,m3;//判断的数字 for (int i = 0;i < m;i ++) {cin>>m1>>m2>>m3;if (m1 == 1) {a[m3-1][m2-1] = 1;a[m2-1][m3-1] = 1;}if (m1 == 2) {myqueue.push(m2);while(myqueue.size()) {top = myqueue.front();a[top-1][top-1] += m3;myqueue.pop(); for(int j = 0;j < n;j ++) {if(a[top-1][j] == 1) {if(b[top-1][j] == 1) {continue;}b[top-1][j] = 1;b[j][top-1] = 1;myqueue.push(j+1);}}}for (int i = 0;i < n;i ++) {for (int j = 0;j < n;j ++) {b[i][j] = 0; } }}}for (int i = 0;i < n;i ++) {for (int j = 0;j < n;j ++) {cout<<a[i][j]<<" "; } cout<<endl;}return 0;
}
第十题的代码是错误的,我还在改正,后面对了,我会重新修改发布。希望有小伙伴可以与我探讨一下思路,大家一起分享,一起进步!!!