20-21(2)第5次线上赛题解
为什么这次突然做题解了呢
因为这次的题目比较简单
哈哈哈哈哈(doge)
1:签到题-6
题意:
提供 m 个数字,有且仅有一个数字重复,找到该数字。
题解:
使用 set 容器(其实这里可以用 multiset)使用方法参考《[C++STL] set 容器的入门》或者网络/书本中的其他资源
上板子:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { set<int>name; int n; cin >> n; while(n--) { int a; cin >> a; if (name.count(a))cout << a << endl; else name.insert(a); } return 0; }
2:XCPC
题意:
根据提供字符串,判断出X、P、C的个数,判断能组成多少个 XCPC 或 CCPC,(不区分大小写)。
题解:
方法一:先排XCPC后排CCPC,模拟一遍。
方法二:根据XCPC和CCPC的数量关系,判断XCPC和CCPC的个数(找数学关系)。
上板子:
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll pn, cn, in; int main() { ll T; cin >> T; string s; while (T--) { int num = 0; pn = 0, cn = 0, in = 0; cin >> s; for (ll i = 0;i < s.length();i++) { if (s[i] == 'p' || s[i] == 'P')pn++; else if (s[i] == 'c' || s[i] == 'C')cn++; else if (s[i] == 'i' || s[i] == 'I')in++; else continue; } while (in > 0) { in--; if (pn > 0 && cn > 1) { pn -= 1; cn -= 2; } else break; num++; } while (cn > 2) { cn -= 3; if (pn > 0) { pn -= 1; } else break; num++; } cout << num << endl; } return 0; }
3:取石子游戏
题意:
甲、乙、丙三人在玩取石子游戏,初始时甲有 A 个石子,乙有 B 个石子,丙有 C 个石子。
每个回合中,甲会从乙那里拿 a 个石子,乙会从丙那里拿 b 个石子,丙会从甲那里拿 c 个石子。
由于三个人总是同时行动,所以可能会出现这样一种情况:某个回合开始时,乙拥有的石子数量 x 不足 a 个,那么甲只能从乙那里拿 x 个石子,回合结束时,乙拥有的石子数量应该等于在本回合中从丙那里获取的石子数。
你需要计算在 n 个回合后,甲、乙、丙拥有的石子数量。
题解:
模拟每一次行动的结果,只需要判断剩余的石头数量是否大于将被取走的石头数量,避免出现负数就行。
这里我用了条件运算符来减少运算量。
关于 printf 和 scanf :
我学的还不是特别明白,这里就不做解释说明了
上板子:
#include<bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while (t--) { int n, a, b, c, A, B, C; cin >> n >> A >> B >> C >> a >> b >> c; int a1, b1, c1; while (n--) { c1 = (A > c ? c : A); a1 = (B > a ? a : B); b1 = (C > b ? b : C); A = A - c1 + a1; B = B - a1 + b1; C = C - b1 + c1; } printf("%d %d %d\n", A, B, C); } return 0; }
4:中位数-2
题意:
有 n 个数字,有 m 次操作,操作只会是a:发出此时的中位数,b:加入一个数 x。
题解:
先读入 n 个数到 set 容器中,使用循环找到中位数,然后输出中位数或加入一个新的数。
上板子:
#include<bits/stdc++.h> using namespace std; int main() { int n, m, x; cin >> n >> m; multiset<int>t; for (int i = 0; i < n; i++) { cin >> x;//可以用 scanf("%d", &x),减少时间 t.insert(x); } multiset<int>::iterator it = t.begin(); for (int i = 1; ; ++it, ++i) { if (i == (t.size() + 1) / 2)break;//找到中间的那个数,如果为偶数,那就存较小的数 } while (m--) { string s; cin >> s; if (s == "Query") { if (t.size() % 2 == 0) cout << (*it++ + *it--) / 2 << endl; else cout << *it << endl; } else if (s == "New") { cin >> x; t.insert(x); if (t.size() % 2 == 0) { if (x < *it)it--; } else if (x > *it)it++; } } return 0; }
5:生成排列
题意:
现在给你 n 个数字,你每次可以将其中的任意一个数字进行加一或减一的操作,请问你至少需要操作多少次才能使其包含 1 ~ n 所有数字。
题解:
记得开long long!
上板子:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int a[100020]; int main() { int T; cin >> T; while (T--) { ll ans = 0; int n; cin >> n; for (int i = 0;i < n;i++) cin >> a[i]; sort(a, a + n); for (int i = 0;i < n;i++) ans += abs(a[i] - i - 1); cout << ans << endl; } return 0; }
最后一道不会写
制作:BDT20040
祝大家学习进步,出题组早日秃头(bushi)