胡凡 《算法笔记》 上机实战训练指南 3.1 简单模拟
Posted 临风而眠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了胡凡 《算法笔记》 上机实战训练指南 3.1 简单模拟相关的知识,希望对你有一定的参考价值。
胡凡 《算法笔记》 上机实战训练指南 3.1
持续更新中 , 菜鸡的刷题笔记…
大学到现在了还没咋好好刷过题,该push自己了…
文章目录
- 胡凡 《算法笔记》 上机实战训练指南 3.1
- 3.1 简单模拟
- 【PAT B1001】害死人不偿命的(3n+1)猜想
- 【PAT B1032】挖掘机技术哪家强
- 【PAT B1011】A+B 和 C
- 【PAT B1016】部分A+B
- 【PAT B1026】程序运行时间
- 【PAT B1046】划拳
- 【PAT B1008】数组元素循环右移问题
- 【PAT B1012】数字分类
- 【PAT B1018】锤子剪刀布
- 【PAT A1042】Shuffling Machine
- 【PAT A1046】Shortest Distance
- 【PAT A1065】A+B and C(64bit)
- 【PAT B1010】一元多项式求导
- 【PAT A1002】A+B for Polynomials
- 【PAT A1009】Product of Polynomials
- 参考资料
3.1 简单模拟
【PAT B1001】害死人不偿命的(3n+1)猜想
-
AC代码
#include <iostream> using namespace std; int main() int n; scanf("%d",&n); int res; int step = 0; while( n != 1) if(n % 2 == 0) n /= 2; else n = ( 3 * n + 1) / 2; step += 1; cout << step; return 0;
-
简洁写法
if (n % 2) n = (n * 3 + 1) / 2; else n /= 2;
【PAT B1032】挖掘机技术哪家强
-
一开始的代码
- 只过了一个测试点
#include <cstdio> int score[10010]=0; int main() int N; scanf("%d",&N); int maxScore; int index,num; int residx ; for(int i = 1; i <= N; i ++) scanf("%d%d",&index,&num); score[index]+=num; maxScore = score[1]; for (int i = 2; i <= N; i ++) if(score[i] > maxScore) maxScore = score[i]; residx = i; printf("%d %d",residx,score[residx]); return 0;
-
上面的代码的漏洞在于,如果第一个学校的总分就是最高的,无法输出
-
于是,将自己的代码里面的 residx初始化为1,但还是有数据点没通过
- 去参考了这个:【PAT B1032】挖掘机技术哪家强 - Chilan Yuk的文章 - 知乎 https://zhuanlan.zhihu.com/p/397334909
-
看了半天,不知道为啥错,仔细一看,数组开小了…
- 10的5次方… 就开了个10010… 蚌埠住了… 这里浪费了一堆时间
-
AC代码
#include <cstdio> int score[100010]; int main() int N; scanf("%d",&N); int maxScore; int index,num; int residx = 1; for(int i = 1; i <= N; i ++) scanf("%d%d",&index,&num); score[index]+=num; maxScore = score[1]; for (int i = 1; i <= N; i ++) if(score[i] >= maxScore) maxScore = score[i]; residx = i; printf("%d %d",residx,score[residx]); return 0;
-
另外,自己写的代码 两个for循环其实可以合并 ,就像题解里面只写了一个while循环那样
#include <cstdio> int score[100010]; int main() int N; scanf("%d",&N); int maxScore=0; int index,num; int residx = 1; for(int i = 1; i <= N; i ++) scanf("%d%d",&index,&num); score[index]+=num; if(score[i] > maxScore) maxScore = score[i]; residx = i; printf("%d %d",residx,score[residx]); return 0;
【PAT B1011】A+B 和 C
-
AC代码
#include <iostream> using namespace std; int main() int T; long long A,B,C; cin >> T; int i=1; while(T--) cin>> A >> B >> C; if(A + B > C) cout<<"Case #"<<i<<": true"<<endl; else cout<<"Case #"<<i<<": false"<<endl; i+=1; return 0;
【PAT B1016】部分A+B
-
AC代码
#include <iostream> using namespace std; int getN(int a, int b) int p = 0; int num = 1; while(a) if( a % 10 == b) p += num*b; num *= 10; a /= 10; return p; int main() int A,D_A,B,D_B; int P_A=0,P_B=0; cin >> A >> D_A >> B >> D_B; int numA=1; int numB=1; P_A = getN(A,D_A); P_B = getN(B,D_B); cout<< P_A + P_B <<endl; return 0;
【PAT B1026】程序运行时间
-
思路比较顺畅,但是一开始的答案格式错了,时分秒的输出要保证不足两位时高位用0 补充
-
错误格式代码
#include <iostream> using namespace std; int main() int C1, C2; cin >> C1 >> C2; double S = (C2-C1)/100.0; int T; int hh, mm , ss; if(S < (C2-C1)/100+0.5) T = (C2-C1) / 100; else T = (C2-C1) / 100 + 1; hh = T / 3600; mm = T / 60 - hh * 60; ss = T - hh * 3600 - mm * 60; printf("%d:%d:%d",hh,mm,ss);
-
正确AC代码
#include <iostream> using namespace std; int main() int C1, C2; cin >> C1 >> C2; double S = (C2-C1)/100.0; int T; int hh, mm , ss; if(S < (C2-C1)/100+0.5) T = (C2-C1) / 100; else T = (C2-C1) / 100 + 1; hh = T / 3600; mm = T / 60 - hh * 60; ss = T - hh * 3600 - mm * 60; printf("%02d:%02d:%02d",hh,mm,ss);
-
-
但感觉自己的代码还是不够简洁
这是参考链接里面那位知乎博主写的
#include <iostream> #include <cstdio> #include <cmath> using namespace std; int main() int C1, C2; cin >> C1 >> C2; int time = round((C2 - C1)/100.0); printf("%02d:%02d:%02d\\n",time/3600,time%3600/60,time%60);
这本书上给的答案👇
书上避免浮点数运算的写法: C2-C1的末两位不少于50时,说明除以100后需要进位
#include <iostream> #include <cstdio> #include <cmath> using namespace std; int main() int C1, C2; cin >> C1 >> C2; int ans = C2 - C1; if( ans % 100 >= 50) ans = ans / 100 + 1; else ans = ans / 100; // int time = round((C2 - C1)/100.0); printf("%02d:%02d:%02d\\n",ans /3600,ans %3600/60,ans%60);
【PAT B1046】划拳
-
AC代码
#include <iostream> #include <cstdio> using namespace std; void getCount(int jha, int jhu, int yha, int yhu,int& jf , int& yf) if((jhu == jha + yha)&&(yhu == jha + yha) || (jhu != jha + yha)&&(yhu != jha + yha)) return; else if(jhu == jha + yha) yf += 1; if(yhu == jha + yha) jf += 1; int main() int N; int jha,jhu,yha,yhu; int jf = 0 , yf = 0; cin >> N; while(N--) cin >> jha >> jhu >> yha >> yhu; getCount(jha,jhu,yha,yhu,jf,yf); cout<<jf<<" "<<yf; return 0;
想到引用不错,但还是感觉自己写的有点复杂
-
书上答案👇比较简洁
#include <iostream> #include <cstdio> using namespace std; int main() int N; //条数 cin >> N; int failA, failB; //输的次数 for(int i = 0 ;i < N ; i++) int a1,a2 ,b1, b2; cin>> a1 >> a2 >> b1 >> b2; //甲猜中乙没有猜中 if(a1 + b1 == a2 && a1 + b1 !=b2) failB++; //甲没猜中乙猜中了 else if( a1 + b1 != a2 && a1 + b1 == b2) failA ++; cout << failA << " " << failB; return 0;
既然平局不加分,那就直接表示一个人赢的情况,代码更简洁
【PAT B1008】数组元素循环右移问题
-
AC居然搞了大半天…
一开始只用一个数组的方法想了大半天… 然后开一个数组的也耗费大半天…(不过其实违背题意了…题目里说不允许使用另外数组的前提下) 因为一开始数组a从i=1开始搞的…
#include <iostream> using namespace std; int N; int M; int a[110]; int b[110]; int main() cin >> N >> M; for(int i = 0; i <= N-1; i ++) cin >> a[i]; // int temp; // for(int i = 1; i <= N; i ++) // // temp = a[i]; // a[i] = a[(i+M)%N]; // a[(i+M)%N] = temp; // for(int i = 0; i <= N-1; i ++) b[(i+M)%N ] = a[i]; //temp = a ; a = b; b = temp; for(int i = 0; i <= N-2; i ++) cout << b[i] << " "; cout << b[N-1]; return 0;
-
知乎博主的做法
思路nb… 启发很大
【PAT B1008】数组元素循环右移问题 - Chilan Yuk的文章 - 知乎 https://zhuanlan.zhihu.com/p/398355139
#include <iostream> using namespace std; int main() int N, M; int arr[105]; cin >> N >> M; for(int i = 0; i < N; i ++) cin >> arr[(i+M)%N]; cout << arr[0]; if(N > 1) for(int i = 1; i < N; i ++) cout << " " << arr[i];
-
书上的思路
其实也是只管输出就行, cnt与N比较大小是用来控制格式
cnt记录已经输出的数的个数
右移M位,就相当于N-M号元素变成了新数组的第一个元素
于是先输出N-M到N-1号元素,再输出0到N-M-1号即可
#include <iostream> using namespace std; int main() int a[110]; int N, M, cnt = 0; cin >> N >> M; M = M % N; for( int i = 0 ; i < N; i++) cin >> a[i]; for( int i = N - M; i < N; i++) cout << a[i]; cnt++; if(cnt < N ) cout << " "; for( int i = 0; i < N - M; i++) cout << a[i]; cnt ++; if(cnt < N ) cout << " "; return 0;
【PAT B1012】数字分类
-
一开始的代码
#include <iostream> #include <cstdio> using namespace std; double A[6]; int cnt[6]《R语言实战》自学笔记41-生成频数表