本文是 AtCoder Beginner Conteset(ABC)382 的总结笔记。
A - Daily Cookie
Problem:A - Daily Cookie
省略。
B - Daily Cookie 2
Problem:B - Daily Cookie 2
把字符串 S S S 后面的 k k k 个@改成 . 输出。
#include <bits/stdc++.h> using namespace std;typedef long long LL;typedef pair<int , int > PII;void solve () { int n, k; cin >> n >> k; string s; cin >> s; for (int i = n - 1 ; i >= 0 ; i--) { if (!k) break ; if (s[i] == '@' ) { k--; s[i] = '.' ; } } cout << s << endl; } int main () { cin.tie (0 ); ios_base::sync_with_stdio (false ); solve (); return 0 ; }
C - Kaiten Sushi
Problem:C - Kaiten Sushi
贪心。
题目:
有编号 1 ∼ N 1 \sim N 1 ∼ N 的 N N N 个人,每个人有阈值 A i A_i A i ,只吃超过阈值的食物。
有 1 ∼ M 1\sim M 1 ∼ M 的 M M M 份寿司,每个寿司有美味度 B j B_j B j ,依次经过上面的每个人。只要美味度高于这个人,就会被这个人吃掉。
输出每份寿司被谁吃掉。
思路:
对于 A A A 来说,只要是高于它阈值的寿司,都会被吃掉。所以将所有寿司按照降序排列,从头开始遍历 A A A 的各个人即可。
#include <bits/stdc++.h> using namespace std;typedef long long LL;typedef pair<int , int > PII;const int N = 2e5 + 10 ;int n, m;int A[N];PII B[N]; int res[N]; bool cmp (const PII& a, const PII& b) { return a.first > b.first; } void solve () { cin >> n >> m; for (int i = 0 ; i < n; i++) cin >> A[i]; for (int i = 0 ; i < m; i++) { cin >> B[i].first; B[i].second = i; } sort (B, B + m, cmp); memset (res, -1 , sizeof res); for (int i = 0 , index = 0 ; i < n; i++) { while (A[i] <= B[index].first) { res[B[index].second] = i + 1 ; index++; } } for (int i = 0 ; i < m; i++) cout << res[i] << endl; } int main () { cin.tie (0 ); ios_base::sync_with_stdio (false ); solve (); return 0 ; }
D - Keep Distance
Problem:D - Keep Distance
DFS + 剪枝
题目:
打印长度为 N N N 并满足下面两个条件的字典序序列 A A A :
思路:
题目中有个重要的约束条件:前一个数 A i − 1 A_{i-1} A i − 1 与后一个数 A i A_i A i 距离相差 10 10 10 以上。
利用这个约束条件可以剪枝 DFS 的递归过程,大大减少时间复杂度。
#include <bits/stdc++.h> using namespace std;typedef long long LL;typedef pair<int , int > PII;int n, m;vector<vector<int >> res; vector<int > temp; void dfs (int x, int u) { if (u == n) { res.push_back (temp); return ; } if (x > m) return ; for (int i = x + 10 ; i <= m - 10 * (n - 1 - u); i++) { temp.push_back (i); dfs (i, u + 1 ); temp.pop_back (); } } void solve () { cin >> n >> m; for (int i = 1 ; i <= m - 10 * (n - 1 ); i++) { temp.push_back (i); dfs (i, 1 ); temp.pop_back (); } cout << res.size () << endl; for (auto & x : res) { for (auto t : x) cout << t << " " ; cout << endl; } } int main () { cin.tie (0 ); ios_base::sync_with_stdio (false ); solve (); return 0 ; }
E - Expansion Packs
Problem:E - Expansion Packs
概率题
题目:
有无限个口袋,每个口袋里有 N N N 张卡片。第 i i i 张卡片位稀有卡的概率为 P i P_i P i 。
一个个打开口袋。求累计获得 X X X 张稀有卡的时候,打开口袋的期望值。
限制条件:
1 ≤ N ≤ 5000 1 \leq N \leq 5000 1 ≤ N ≤ 5000
1 ≤ X ≤ 5000 1 \leq X \leq 5000 1 ≤ X ≤ 5000
1 ≤ P i ≤ 100 1 \leq P_i \leq 100 1 ≤ P i ≤ 100
思路:
TODO