摘要
L2-3
名人堂与代金券 - 团体程序设计天梯赛练习2:排序+栈+队列
L2-2
冰岛人 - 团体程序设计天梯赛练习2:排序+栈+队列
L2-1
简单计算器 - 团体程序设计天梯赛练习2:排序+栈+队列
7-4
口罩发放 - 团体程序设计天梯赛练习2:排序+栈+队列
7-5
包装机 - 团体程序设计天梯赛练习2:排序+栈+队列
7-6
清点代码库 - 团体程序设计天梯赛练习2:排序+栈+队列
7-7
插松枝 - 团体程序设计天梯赛练习2:排序+栈+队列
7-8
老板的作息表 - 团体程序设计天梯赛练习2:排序+栈+队列
L2-3 名人堂与代金券
题解
有N个人的邮箱 和 成绩,前K名可以进入名人堂。
总评分在 [G, 100] 区间内者,可以得到 50 元 PAT 代金券;在 [60, G)
区间内者,可以得到 20 元PAT代金券。
求奖金总数 和 进入名人堂的名单。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <bits/stdc++.h> using namespace std;const int maxn = 1e5 + 5 ;struct stu { string name; int sco,rk; bool operator <(const stu & rhs){ if (sco != rhs.sco) return sco > rhs.sco; return name < rhs.name; } }s[maxn];int n,g,k,sum;int main (void ) { cin>>n>>g>>k; for (int i = 1 ; i <= n ; i ++){ cin>>s[i].name>>s[i].sco; if (s[i].sco >= g && s[i].sco <= 100 ) sum += 50 ; if (s[i].sco >= 60 && s[i].sco < g) sum += 20 ; } cout<<sum<<"\n" ; sort (s+1 ,s+1 +n); for (int i = 1 ; i <= n; i ++){ if ((i == 1 ) || (s[i].sco < s[i-1 ].sco)) s[i].rk = i; else s[i].rk = s[i-1 ].rk; } int t = 1 ; while (t <= n && s[t].rk <= k){ cout<<s[t].rk<<" " <<s[t].name<<" " <<s[t].sco<<"\n" ; t++; } return 0 ; }
L2-2 冰岛人
题解
根据冰岛人的姓,可以判断其 性别 和 父亲。
题目要求我们:
1)判断2人的性别相同/不同
2)判断2人是否五代之内有相同祖先。
用哈希表存储性别,进行判断1);然后,根据每个人的父亲,构造一张谱系树图,进行判断2)。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <bits/stdc++.h> using namespace std;const int maxn = 2e5 ;int n,m,cnt; unordered_map<string, string> pre; unordered_map<string, bool > g; set<string > v;bool judge (string q1, string q2) { for (int i = 1 ; i <= 4 ; i ++){ string temp = q2; while (true ){ if (q2 == q1) return false ; if (!pre.count (q2)) break ; else q2 = pre[q2]; } if (!pre.count (q1)) break ; q1 = pre[q1]; q2 = temp; } return true ; }string solve () { string q1,q2,str; cin>>q1>>str>>q2>>str; if (!v.count (q1) || !v.count (q2)) return "NA" ; if (g[q1] == g[q2]) return "Whatever" ; if (judge (q1,q2) && judge (q2,q1)) return "Yes" ; return "No" ; }int main (void ) { cin>>n; for (int i = 1 ; i <= n ; i ++){ string s1,s2; cin>>s1>>s2; v.insert (s1); if (s2. back () == 'm' ){ g[s1] = true ; }else if (s2. back () == 'f' ){ g[s1] = false ; }else if (s2. back () == 'n' ){ g[s1] = true ; pre[s1] = s2. substr (0 ,s2.l ength() - 4 ); }else if (s2. back () == 'r' ){ g[s1] = false ; pre[s1] = s2. substr (0 ,s2.l ength() - 7 ); } } cin>>m; while (m--){ cout<<solve ()<<"\n" ; } return 0 ; }
L2-1 简单计算器
题解
题目要求我们构造2个栈,1个用来存储数字,1个用来存储运算符。
每次从栈1中取出2个数字,栈2中取出一个运算符,将结果存入栈1。
进行模拟,直到栈2为空,输出结果即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <bits/stdc++.h> using namespace std; stack<int > s1; stack<char > s2;int n;int cal (int a, int b, char op) { if (op == '-' ) return a-b; if (op == '+' ) return a+b; if (op == '*' ) return a*b; if (op == '/' ){ if (b == 0 ){ cout<<"ERROR: " <<a<<"/" <<b<<"\n" ; exit (0 ); } return a/b; } return -1 ; }int main (void ) { cin>>n; for (int i = 1 ; i <= n ; i ++){ int t;cin>>t; s1. push (t); } for (int i = 1 ; i <= n-1 ; i ++){ char c;cin>>c; s2. push (c); } while (!s2. empty ()){ int n1 = s1. top ();s1. pop (); int n2 = s1. top ();s1. pop (); char op = s2. top ();s2. pop (); s1. push (cal (n2,n1,op)); } cout<<s1. top (); return 0 ; }
7-4 口罩发放
题解
题目的任务包括2个:
1)对于每天的申请列表,按题目给定顺序,输出合法的申请,即 满足
A.身份证合法 B.间隔超过P天 的申请
2)按题目给定顺序,输出每个身体状况为1的病人名单。
注意:1)和2)要求的输出顺序规则不同。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #include <bits/stdc++.h> using namespace std;struct record { string name,card,mm; int sta,tim,idx; bool operator <(const record & rhs){ if (tim != rhs.tim) return tim < rhs.tim; return idx < rhs.idx; } };struct person { string name,card; };int d,p; unordered_map<string, int > lastDay; vector<person> sick;bool judge_card (string card) { if (card.length () != 18 ) return false ; for (int i = 0 ; i < 18 ; i ++){ if (!(card[i] >= '0' && card[i] <= '9' )) return false ; } return true ; }int get_time (string s) { int h = (s[0 ] - '0' )*10 + (s[1 ] - '0' ); int m = (s[3 ] - '0' )*10 + (s[4 ] - '0' ); return 60 *h + m; }void print_sick () { for (auto it : sick){ cout<<it.name<<" " <<it.card<<"\n" ; } }void solve (int day) { int t,s; cin>>t>>s; vector<record> v; for (int i = 1 ; i <= t ; i ++){ record r; cin>>r.name>>r.card>>r.sta>>r.mm; r.idx = i; r.tim = get_time (r.mm); v.push_back (r); if (judge_card (r.card) && r.sta == 1 ){ bool vis = false ; for (auto it : sick){ if (it.card == r.card){ vis = true ; break ; } } if (!vis) sick.push_back ({r.name, r.card}); } } sort (v.begin (),v.end ()); for (auto it : v){ if (judge_card (it.card)){ if (s > 0 && (!lastDay.count (it.card) || day - lastDay[it.card] > p)){ cout<<it.name<<" " <<it.card<<endl; lastDay[it.card] = day; s--; } } } }int main (void ) { cin>>d>>p; for (int i = 1 ; i <= d ; i ++){ solve (i); } print_sick (); return 0 ; }
7-5 包装机
题解
题目给定了N个运输带,每个运输带上有M个物品,用字符表示,栈内最多存L个物品。
每次按下按钮,若按钮为0,从栈内取出1个物品;若按钮为其他数字,从该下标的运输带上取下物品,放入栈中。
栈内最多存放L个物品,若超过,先取出1个。
输出栈内取出的物品顺序。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <bits/stdc++.h> using namespace std;const int maxn = 105 ;int n,m,l; stack<char > s; queue<char > q[maxn];int main (void ) { cin>>n>>m>>l; for (int i = 1 ; i <= n ; i ++){ for (int j = 1 ; j <= m ; j ++){ char t; cin>>t; q[i].push (t); } } int op; while (cin>>op, op != -1 ){ if (op == 0 ){ if (!s.empty ()){ cout<<s.top (); s.pop (); } }else { if (!q[op].empty ()){ if (s.size () >= l){ cout<<s.top (); s.pop (); } s.push (q[op].front ()); q[op].pop (); } } } return 0 ; }
7-6 清点代码库
题解
给定 N个 数组,每个数组包含M个整数。
我们需要求N个数组中的重复项,并按 重复数 > 数组大小
的规则输出。
注意:这里的数组大小不是长度,指的是vector的排序规则。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <bits/stdc++.h> using namespace std;struct record { int cnt; vector<int > v; bool operator <(const record & rhs){ if (cnt != rhs.cnt) return cnt > rhs.cnt; return v < rhs.v; } }; map<vector<int >, int > mp; vector<record> ans;int n,m,idx;int main (void ) { cin>>n>>m; for (int i = 1 ; i <= n ; i ++){ vector<int > v; for (int j = 1 ; j <= m ; j ++){ int t;cin>>t; v.push_back (t); } if (!mp.count (v)){ mp[v] = idx++; ans.push_back ({1 ,v}); } else { ans[mp[v]].cnt++; } } cout<<ans.size ()<<"\n" ; sort (ans.begin (),ans.end ()); for (int i = 0 ; i < idx ; i ++){ cout<<ans[i].cnt; for (auto it : ans[i].v){ cout<<" " <<it; } cout<<"\n" ; } return 0 ; }
7-7 插松枝
题解
一个松枝 由 K 个 松枝片组成,松枝片长度必须从下到上依次递减。
工人每次从 N
个物品的传送带上取下一个松枝片,插入当前的松枝干(不限数量)上。
此外,还有一个临时存放松枝片的小盒子,小盒子最多存放M个松枝片。小盒子上若有松枝片,优先级高于传送带。
将松枝放到成品篮,制作下一个松枝片 的情况如下:
(1)小盒子已经满了,但传送带上取到的松针仍然不满足要求。
(2)小盒子中最上面的松针不满足要求,但推送器上已经没有松针了。
(3)松枝干上松针数量达到K个。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 #include <bits/stdc++.h> using namespace std;int n,m,k; vector<vector<int > > ans; vector<int > temp; stack<int > s; queue<int > q;bool judge (int x) { if (temp.empty ()) return true ; if (x <= temp.back ()) return true ; return false ; }void insert (int x) { temp.push_back (x); if (temp.size () == k){ ans.push_back (temp); temp.clear (); } }void clear_cur () { if (!temp.empty ()){ ans.push_back (temp); temp.clear (); } }void print () { for (auto v : ans){ if (!v.empty ()) cout<<v.front (); for (int i = 1 ; i < v.size () ; i ++){ cout<<" " <<v[i]; } cout<<"\n" ; } }int main (void ) { cin>>n>>m>>k; for (int i = 1 ; i <= n ; i ++){ int t; cin>>t; q.push (t); } while (!q.empty ()){ if (!s.empty () && judge (s.top ()) ){ insert (s.top ()); s.pop (); continue ; } if (!q.empty () && judge (q.front ())){ insert (q.front ()); q.pop (); }else { if (s.size () < m){ s.push (q.front ()); q.pop (); }else { clear_cur (); } } } while (!s.empty ()){ if (judge (s.top ())){ insert (s.top ()); s.pop (); }else { clear_cur (); } } clear_cur (); print (); return 0 ; }
7-8 老板的作息表
题解
给定一个作息表,格式如下:
1 2 3 4 5 Nhh: mm:ss - hh:mm:ss hh: mm:ss - hh:mm:ss ...hh: mm:ss - hh:mm:ss
要求该作息表未涵盖的一天内的时间段【一天指的是00:00:00 -
23:59:59】。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <bits/stdc++.h> using namespace std;struct record { int t1,t2; bool operator <(const record & rhs){ return t1 < rhs.t1; } };int n; deque<record> dq;void print (int t1, int t2) { printf ("%02d:%02d:%02d - %02d:%02d:%02d\n" , t1/3600 ,(t1%3600 )/60 ,t1%60 , t2/3600 ,(t2%3600 )/60 ,t2%60 ); }int main (void ) { scanf ("%d" , &n); for (int i = 1 ; i <= n ; i ++){ int h1,m1,s1,h2,m2,s2; scanf ("%d:%d:%d - %d:%d:%d" , &h1, &m1, &s1, &h2, &m2, &s2); int sum1 = h1*3600 + m1*60 + s1; int sum2 = h2*3600 + m2*60 + s2; dq.push_back ({sum1, sum2}); } sort (dq.begin (), dq.end ()); int f = 23 *3600 + 59 *60 + 59 ; dq.push_front ({0 ,0 }); dq.push_back ({f,f}); for (int i = 0 ; i < dq.size ()-1 ; i ++){ if (dq[i].t2 != dq[i+1 ].t1){ print (dq[i].t2, dq[i+1 ].t1); } } return 0 ; }