考虑到PAT甲级考试和开学后的XCPC比赛,决定寒假把PAT (Advanced Level) Practice刷完,进度条会在这篇博客下更新。由于主要以记录为主,大体上不会像单篇题解那么详细,但是对问题的思考,代码的简洁性、可读性还是有保障的,欢迎看到的小伙伴和我讨论
2021.1.10
1001 A+B Format (20分)
很久没写题了,没想到卡了半个小时,惭愧。这里是要把结果用逗号分隔成三组,即以千为单位,不足的话则不必要填逗号,我最多只添了一个逗号,要看清题目意思再动笔
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; int a, b, c, d; int main(){ scanf("%d%d", &a, &b); int num = a + b, tmp = abs(num); c = tmp / 1000000, tmp %= 1000000; d = tmp / 1000, tmp %= 1000; if(num<0) printf("-"); if(abs(num)>=1000000) printf("%d,%03d,%03d", c, d, tmp); else if(abs(num)>=1000) printf("%d,%03d", d, tmp); else printf("%d", tmp); }
其他做法:
https://zhuanlan.zhihu.com/p/64035132
https://www.cnblogs.com/chenchen-12/p/10084579.html
1002 A+B for Polynomials (25分)
由于多项式合并后,可能出现原本是-1和+1,相加后就成为0的情况,这不能通过在输入时计数方式判断最后的非零项有多少
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 1e3+100; int n, cnt, id; float a[maxn], val; int main(){ for(int i = 1; i <= 2; i++){ scanf("%d", &n); for(int j = 1; j <= n; j++){ scanf("%d%f", &id, &val); //if(a[id]==0) cnt++; a[id] += val; } } for(int i = 0; i < maxn; i++) if(a[i]!=0) cnt++; printf("%d", cnt); for(int i = 1000; i >= 0; i--){ if(a[i]!=0) printf(" %d %.1f", i, a[i]); } }
2021.1.12
1005 Spell It Right (20分)
注意数字对应的英文要写对,submit的时候不要把debug的信息也显示
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <cmath> using namespace std; const int maxn = 150; map<int, string> a; string s, tmp; int ans; void init(){ a[0] = "zero", a[1] = "one", a[2] = "two", a[3] = "three", a[4] = "four"; a[5] = "five", a[6] = "six", a[7] = "seven", a[8] = "eight", a[9] = "nine"; } int main(){ init(); cin >> s; for(int i = 0; s[i]; i++) ans += s[i]-'0'; tmp = to_string(ans); //cout << tmp << endl; int len = tmp.length(); for(int i = 0; i < len; i++){ cout << a[tmp[i]-'0']; if(i!=len-1) cout << " "; } }
1006 Sign In and Sign Out (25分)
string比较大小即可
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <cmath> using namespace std; const int maxn = 1e3+100; int n; string id, a, b, min_s = "23:59:59", max_s = "00:00:00", in, out; int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++){ cin >> id >> a >> b; if(a<min_s) min_s = a, in = id; if(b>max_s) max_s = b, out = id; } cout << in << " " << out; }
1007 Maximum Subsequence Sum (25分)
基本的dp问题,最大连续区间和:
定义dp[i]为以i结尾的最大连续和,转移方程为:dp[i] = max(a[i], dp[i-1],+a[i])
坑点在于英文阅读理解:
If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.
这句话等价于当最大区间和小于0时,输出整个序列的第一个元素和最后一个元素。还有个是我自己没看清楚,应该输出最小下标对应的元素,而不是下标。
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <cmath> #define ll long long #define inf 0x3f3f3f using namespace std; const int maxn = 1e4+100; int n, id, front, tear, ans = -1; int a[maxn], dp[maxn]; int main(){ scanf("%d", &n); front = 1, tear = n; for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); if(dp[i-1]>0) dp[i] = dp[i-1] + a[i]; else dp[i] = a[i], id = i; if(ans<dp[i]) ans = dp[i], front = id, tear = i; } printf("%d %d %d", ans>=0 ? ans : 0, a[front], a[tear]); }
1008 Elevator (20分)
模拟题
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <cmath> #define ll long long #define inf 0x3f3f3f using namespace std; const int maxn = 1e4+100; int n, sum, now, tmp; int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++){ scanf("%d", &tmp); int num = tmp-now; sum += num > 0 ? num*6 : num*(-4); now = tmp; } sum += 5*n; printf("%d", sum); }
1009 Product of Polynomials (25分)
模拟多项式乘法,注意细节即可
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <cmath> #define ll long long #define inf 0x3f3f3f using namespace std; const int maxn = 2e3+100; int n, m, id, cnt; float val, ans[maxn]; struct node{ int id; float val; }now[1100]; int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d%f", &now[i].id, &now[i].val); scanf("%d", &m); for(int i = 1; i <= m; i++){ scanf("%d%f", &id, &val); for(int j = 1; j <= n; j++){ ans[id+now[j].id] += now[j].val*val; } } for(int i = maxn-1; i >= 0; i--) if(ans[i]!=0) cnt++; printf("%d", cnt); for(int i = maxn-1; i >= 0; i--){ if(ans[i]!=0) printf(" %d %.1f", i, ans[i]); } }
2021.1.13
晚上看了很久的二分,不太理解其中的细节,卡了一晚上,对自己的智商感到深深的怀疑
1004 Counting Leaves (30分)
2021.1.14
感觉很久没写算法手已经很生了,主要是很多算法自己明明思考证明过,也写过,但是现在再写一遍还是会忘记。反思后觉得,还是要脚踏实地多刷题才是根本,然后就是感性理解算法是很重要的一环,一定要在脑海里有个形象的记忆,懂其中的思想。因为就算之前很严密的证明过一次,过段时间后这种严密的证明大概率会忘掉很多,再来一遍也很繁琐,但是不去细看又不太懂为什么他那样做是正确的,又会感到很疑惑。能证明这个算法的正确性和想出来这个算法那还是不太一样的。有人交流往往是幸福的,尤其是在现实中,没有的话只能在网上多看看优质的文章与讨论。(这篇博客给了我些感悟)
1003 Emergency (25分)
1011 World Cup Betting (20分)
水题
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <vector> #include <cmath> #define ll long long #define pb push_back #define inf 0x3f3f3f #define pii pair<int, int> using namespace std; const int maxn = 1e4+100; float a, b, c, res = 1, ans; char s[4]; int main(){ for(int i = 1; i <= 3; i++){ scanf("%f%f%f", &a, &b, &c); float tmp = max(a, max(b, c)); if(tmp==a) s[i] = 'W'; else if(tmp==b) s[i] = 'T'; else s[i] = 'L'; res *= tmp; } ans = (res*0.65-1)*2; printf("%c %c %c %.2f", s[1], s[2], s[3], ans); }
1012 The Best Rank (25分)
注意不要发生复制粘贴后代码未修改的低级错误,再就是数据范围,不然会出现段错误。对数据排序,最后二分查找相应位置即可。
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <vector> #include <cmath> #define ll long long #define pb push_back #define inf 0x3f3f3f #define pii pair<int, int> using namespace std; const int maxn = 2e3+100; struct score{ int c, m, e, a; }a[1000100]; bool cmp(int a, int b){ return a > b; } int n, m, id; int x[maxn], y[maxn], z[maxn], w[maxn]; bool vis[1000100]; int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++){ scanf("%d", &id), vis[id] = 1; scanf("%d%d%d", &a[id].c, &a[id].m, &a[id].e); //cout << a[id].c << " "<< a[id].c << " "<< a[i].e <<endl; a[id].a = (a[id].c+a[id].m+a[id].e)/3; x[i] = a[id].c, y[i] = a[id].m, z[i] = a[id].e, w[i] = a[id].a; } sort(x+1, x+1+n, cmp), sort(y+1, y+1+n, cmp), sort(z+1, z+1+n, cmp), sort(w+1, w+1+n, cmp); while(m--){ scanf("%d", &id); if(!vis[id]){ printf("N/A\n"); continue; } int r1 = lower_bound(x+1, x+1+n, a[id].c, greater<int>())-x; int r2 = lower_bound(y+1, y+1+n, a[id].m, greater<int>())-y; int r3 = lower_bound(z+1, z+1+n, a[id].e, greater<int>())-z; int r4 = lower_bound(w+1, w+1+n, a[id].a, greater<int>())-w; int r = min(min(r1, r2), min(r3, r4)); printf("%d ", r); if(r==r4) printf("A\n"); else if(r==r1) printf("C\n"); else if(r==r2) printf("M\n"); else if(r==r3) printf("E\n"); } }
2021.1.15
1014 Waiting in Line (30分)
一道模拟题,显然的思路是开始先将客户依次排到队列中去,排满后剩下的客户选择排到业务处理的最快的队伍中去,记录时间戳即可。
难倒是不难,就是有些细节需要想清楚,我在栽在两个坑点上:
- 判断一个客户无法完成服务是根据他的开始服务时间应该在15:00之前,而不是以结束时间为依据
- 根据思路分两步处理,但是忽略了n*m可能会比k要大,造成数据输入不足
写的时候想清楚这个过程就好,重点在于细节没想到位,搜完博客后发现第一个坑点,第二个坑点苦思冥想了很久,不过最后写出来的代码相比其他人要简洁的多,并且有附加的附加调试信息
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #define inf 0x3f3f3f3f using namespace std; const int maxn = 2e3+100; int n, m, k, q, w[maxn]; int que[maxn][maxn], id[maxn], p[maxn], sum[maxn][maxn], res[maxn]; int main(){ scanf("%d%d%d%d", &n, &m, &k, &q); for(int i = 1; i <= min(n*m, k); i++) { scanf("%d", &w[i]); que[(i-1)%n][(i-1)/n+1] = i, id[(i-1)%n]++; res[i] = sum[(i-1)%n][(i-1)/n+1] = sum[(i-1)%n][(i-1)/n] + w[i]; } for(int i = 0; i <= n-1; i++) p[i] = 1; for(int i = min(n*m, k)+1; i <= k; i++){ scanf("%d", &w[i]); int tmp = inf, now; for(int j = 0; j <= n-1; j++){ if(sum[j][p[j]]<tmp) tmp = sum[j][p[j]], now = j; } p[now]++, id[now]++; que[now][id[now]] = i; res[i] = sum[now][id[now]] = sum[now][id[now]-1] + w[i]; } while(q--){ int query; scanf("%d", &query); //cout << res[query] << endl; if(res[query]-w[query]>=540) printf("Sorry\n"); else printf("%02d:%02d\n", 8+res[query]/60, res[query]%60); } }
reference:
https://www.cnblogs.com/codervivi/p/12867049.html
2021.1.17
1015 Reversible Primes (20分)
1010 Radix (25分)
2021.1.17
从今天开始就要按照专题更加有效的复习了,专题会专门写几篇博客,陆续会把前几天写的题目整理进专题,希望这样写题会更加有效率
1051 Pop Sequence (25分)
1056 Mice and Rice (25分)
2021.1.19
1060 Are They Equal (25分)
1039 Course List for Student (25分)
1047. Student List for Course
2021.1.21
1054 The Dominant Color (20分)
大水题
#include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <vector> #include <cmath> #define ll long long #define inf 0x3f3f3f #define pii pair<int, int> #define pb push_back using namespace std; const int maxn = 1e8+100; int n, m, num, ans, cnt[maxn]; int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ scanf("%d%", &num); if(++cnt[num]>m*n/2) ans = num; } } printf("%d", num); }
1071 Speech Patterns (25分)
1100 Mars Numbers (20分)
2021.1.22
1022 Digital Library (30分)
1063 Set Similarity (25分)
2021.1.24
基础的东西也要常练常思考,知道和掌握是两码事,这里面还有很多细节性的东西,不是说我看懂了一遍就能很快的写对题目
1032 Sharing (25分)
1052 Linked List Sorting (25分)
1074 Reversing Linked List (25分)
2021.1.26
最近有点松懈了,该做的事应该形成习惯,不然会越来越懒
1097 Deduplication on a Linked List (25分)
2021.1.27
早上被说人说了一顿,说能不能干点正经事,我想也是,我这人就是欠骂
1091 Acute Stroke (30point(s))
2021.1.28
1103 Integer Factorization (30分)
1053 Path of Equal Weight (30分)
2021.2.18
1079 Total Sales of Supply Chain (25 分)
1090 Highest Price in Supply Chain (25 分)
1106 Lowest Price in Supply Chain (25 分)
1094 The Largest Generation (25 分)
1043 Is It a Binary Search Tree (25 分)
2021.2.21
1099 Build A Binary Search Tree (30 分)
1064 Complete Binary Search Tree (30 分)
2021.2.22
1020 Tree Traversals (25 分)
1086 Tree Traversals Again (25 分)
1102 Invert a Binary Tree (25 分)
2021.2.23
1066. Root of AVL Tree (25)
2021.2.24
1098 Insertion or Heap Sort (25 分)
1107 Social Clusters (30 分)
2021.2.25
1013 Battle Over Cities (25 分)
1021 Deepest Root (25 分)
1034 Head of a Gang (30 分)
2021.3.2
1018 Public Bike Management (30 分)
2021.3.4
今天开会那会hwx说这做题也需要积累,短时间看不到什么效果,徐老师直接怼了过去,我觉得还是很在理且受用的,“你要什么效果,题目就摆在哪里,你还没有过掉”
1072 Gas Station (30 分)
1087 All Roads Lead to Rome (30 分)
2021.3.5
1049 Counting Ones (30 分)
1069 The Black Hole of Numbers (20 分)
1104 Sum of Number Segments (20分)
2021.3.6
1078 Hashing (25 分)
1145 Hashing - Average Search Time (25 分)
2021.3.7
1041 Be Unique (20 分)
1048 Find Coins (25 分)
1050 String Subtraction (20 分)
1084 Broken Keyboard (20 分)
1092 To Buy or Not to Buy (20 分)
1023 Have Fun with Numbers (20 分)
1024 Palindromic Number (25 分)
2021.3.9
1059 Prime Factors (25 分)
1096 Consecutive Factors (20 分)
1081 Rational Sum (20 分)
2021.3.10
13号马上就要考了,打算明后两天把基础的模板复习下,看一看之前自己做过的题目
1088 Rational Arithmetic (20 分)
1093 Count PAT's (25 分)
1101 Quick Sort (25 分)