PAT(乙级)2019年秋季考试
比赛链接:https://pintia.cn/market/item/1170913498742468608
7-1 B是A的多少倍
题意
将一个数后 $d$ 位截下移到最高位前面,得到的新数是原数的多少倍。
代码
#include <bits/stdc++.h> using namespace std; int main() { string s; int d; cin >> s >> d; string t = s.substr(s.size() - d) + s.substr(0, s.size() - d); printf("%.2f\n", stod(t) / stod(s)); }
7-2 教超冠军卷
题意
给出 $n$ 个购买记录,每个购买记录包含:产品id、单价、销量。统计销量冠军和销售额冠军。
代码
#include <bits/stdc++.h> using ll = long long; using namespace std; int main() { int n; cin >> n; map<string, pair<ll, ll>> mp; ll mx_num = 0, mx_tot = 0; for (int i = 0; i < n; i++) { string s; ll unit, num; cin >> s >> unit >> num; mx_num = max(mx_num, mp[s].first += num); mx_tot = max(mx_tot, mp[s].second += unit * num); } for (auto pr : mp) if (pr.second.first == mx_num) cout << pr.first << ' ' << pr.second.first << "\n"; for (auto pr : mp) if (pr.second.second == mx_tot) cout << pr.first << ' ' << pr.second.second << "\n"; }
7-3 缘分数
题意
正整数 $a$ 和 $b$ 为缘分数,如果二者满足:
\begin{equation}\nonumber a^3 - (a - 1)^3 = (b^2 + (b - 1)^2)^2 \end{equation}
给出 $a$ 所在的区间,寻找该区间内的缘分数。
题解
构造等式右侧的值,判断区间内是否有 $a$ 可以得到构造值即可。
Tips
虽然满足题意,但在测试点中 $(1,1)$ 并没有被算进缘分数里。
代码一
#include <bits/stdc++.h> using ll = long long; using namespace std; int main() { map<ll, ll> mp; for (ll b = 2; b <= 10000; b++) { ll c = b * b + (b - 1) * (b - 1); mp[c * c] = b; } ll l, r; cin >> l >> r; bool fail = true; for (ll a = l; a <= r; a++) { ll c = a * a * a - (a - 1) * (a - 1) * (a - 1); if (mp[c]) { cout << a << ' ' << mp[c] << "\n"; fail = false; } } if (fail) cout << "No Solution" << "\n"; }
代码二
#include <bits/stdc++.h> using namespace std; int main() { vector<pair<int, int>> ans = {{8, 3}, {105, 10}, {1456, 36}, {20273, 133}}; int l, r; cin >> l >> r; bool fail = true; for (auto i : ans) { if (l <= i.first and i.first <= r) { cout << i.first << ' ' << i.second << "\n"; fail = false; } } if (fail) cout << "No Solution" << "\n"; }
7-4 天长地久
题意
天长地久数指一个 $k$ 位正整数 $A$ 满足:
- $A$ 的各位数字之和为 $m$
- $A+1$ 的各位数字之和为 $n$
- $gcd(m,n)$ 是一个大于 $2$ 的素数
给出 $k$ 和 $m$,找出所有的 $A$ 。
题解
如果 $A+1$ 不存在进位,那么 $n = m + 1$,$gcd(m, m + 1) = 1$,所以最后一位数字一定为 $9$ 。
Tips
$for$ 循环的判断条件如果不是 $O_{(1)}$,最好预先计算出来。
代码
#include <bits/stdc++.h> using namespace std; struct P{ int n, A; }; int binpow(int a, int b) { int res = 1; while (b) { if (b & 1) res = res * a; a = a * a; b >>= 1; } return res; } int sum(int n) { int res = 0; while (n) res += n % 10, n /= 10; return res; } bool isprime(int n) { for (int i = 2; i * i <= n; i++) if (n % i == 0) return false; return true; } int main() { int n; cin >> n; for (int Case = 1; Case <= n; Case++) { int k, m; cin >> k >> m; int l = binpow(10, k - 2); int r = binpow(10, k - 1); vector<P> ans; for (int i = l; i < r; i++) { int x = i * 10 + 9; if (sum(x) == m) { int gcd = __gcd(sum(x), sum(x + 1)); if (gcd > 2 and isprime(gcd)) { ans.push_back({sum(x + 1), x}); } } } sort(ans.begin(), ans.end(), [&] (P a, P b) { if (a.n != b.n) return a.n < b.n; else return a.A < b.A; }); cout << "Case " << Case << "\n"; if (ans.size()) { for (P i : ans) cout << i.n << ' ' << i.A << "\n"; } else { cout << "No Solution" << "\n"; } } }
7-5 链表合并
题意
给出两个链表,较长链表的长度至少是较短链表的两倍,将较短的链表反转后每隔两个元素插入较长的链表。
题解
将链式存储结构转为顺序存储结构即可。
Tips
使用数组映射会内存超限。
代码
#include <bits/stdc++.h> using namespace std; map<int, int> Data, Next; int main() { int l1, l2, n; cin >> l1 >> l2 >> n; for (int i = 0; i < n; i++) { int a, d, n; cin >> a >> d >> n; Data[a] = d; Next[a] = n; } vector<int> v1; for (int i = l1; i != -1; i = Next[i]) { v1.push_back(i); } vector<int> v2; for (int i = l2; i != -1; i = Next[i]) { v2.push_back(i); } if (v1.size() < v2.size()) { swap(v1, v2); } reverse(v2.begin(), v2.end()); vector<int> v3; for (int i = 0, j = 0; i < v1.size(); i++) { v3.push_back(v1[i]); if ((i + 1) % 2 == 0 and j < v2.size()) v3.push_back(v2[j++]); } for (int i = 0; i < v3.size(); i++) { cout << setw(5) << setfill('0') << v3[i] << ' '; cout << Data[v3[i]] << ' '; if (i + 1 < v3.size()) cout << setw(5) << setfill('0') << v3[i + 1] << "\n"; else cout << -1 << "\n"; } }

浙公网安备 33010602011771号