AtCoder Beginner Contest 441
个人题解
Nanami^2 Even in the rain.
2026年01月18日
预计阅读 10 分钟
1906 字
A
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}signed main() { // ios::sync_with_stdio(0); // cin.tie(0); // cout.tie(0); int p, q, x, y; cin >> p >> q >> x >> y; if(p <= x && x <= p + 99 && q <= y && y <= q + 99) { puts("Yes"); } else puts("No"); return 0;}B
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}int n, m, q;string S, T;map<char, int> tk, ao;signed main() { // ios::sync_with_stdio(0); // cin.tie(0); // cout.tie(0); cin >> n >> m >> S >> T; for(auto x : S) tk[x] = 1; for(auto x : T) ao[x] = 1; cin >> q; while(q--) { string s; cin >> s; int f1 = 1, f2 = 1; for(auto x : s) { f1 &= tk.count(x); f2 &= ao.count(x); } if(f1 ^ f2) { if(f1) cout << "Takahashi" << endl; else cout << "Aoki" << endl; } else cout << "Unknown" << endl; } return 0;}C
按照 递增排序得到 。 首先答案至少是 ,因为最坏的情况下 杯容积最小的是酒,所以你至少要取溶剂前 大的杯子,这样至少有 的收益。然后贪心选大的,看能不能超过 即可。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = 3e5 + 5;int n, k;ll X, a[N];signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> k >> X; for(int i = 1;i <= n;i++) cin >> a[i]; sort(a + 1, a + n + 1); int ans = n - k + 1; ll res = 0; // for(int i = k;i <= n;i++) res += a[i]; res = a[k]; for(int i = k - 1;i >= 1;i--) { if(res < X) res += a[i], ans++; else break; } if(res >= X) cout << ans << endl; else cout << "-1" << endl; return 0;}D
注意到边数不多,直接 BFS 就好了。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = 2e5 + 5;int n, m, L, S, T;bool v[N];unordered_map<int, bool> mp[12];vector<PII > p[N];struct node { int x, cnt, sum;};void bfs() { queue<node> q; q.push({1, 0, 0}); while(q.size()) { node t = q.front(); q.pop(); int x = t.x, cnt = t.cnt, sum = t.sum; if(cnt == L) { if(S <= sum && sum <= T && !v[x]) { v[x] = 1; } continue; } for(auto [y, z] : p[x]) if(cnt + 1 <= L && sum + z <= T) { q.push({y, cnt + 1, sum + z}); } }}signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m >> L >> S >> T; for(int i = 1;i <= m;i++) { int x, y, z; cin >> x >> y >> z; p[x].pb({y, z}); } bfs(); for(int x = 1;x <= n;x++) if(v[x]) cout << x << " "; cout << endl; return 0;}E
令A是 ,B是 ,C是 。
求出前缀和 ,问题转化为对于每个 ,数一下 满足 。
树状数组完事了。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = 5e5 + 5;int n, a[N], s[N];string st;struct BIT { int c[(N << 1) + 5]; void add(int i, int d) { i += N; for(int x = i;x <= n + N;x += (x & -x)) { c[x] += d; } } int query(int i) { i += N; int res = 0; for(int x = i;x;x -= (x & -x)) { res += c[x]; } return res; }} T;signed main() { // ios::sync_with_stdio(0); // cin.tie(0); // cout.tie(0); cin >> n >> st; st = " " + st; for(int i = 1;i <= n;i++) { if(st[i] == 'A') a[i] = 1; else if(st[i] == 'B') a[i] = -1; else if(st[i] == 'C') a[i] = 0; s[i] = s[i - 1] + a[i]; // printf("s[%d]=%d\n", i, s[i]); } T.add(0, 1); ll ans = 0; for(int i = 1;i <= n;i++) { ans += T.query(s[i] - 1); T.add(s[i], 1); } cout << ans << endl; return 0;}F
注意到 ,时间和空间都是充足的。
先跑一遍背包,得到最大价值
什么情况下必须买一件东西呢?当且仅当删掉它后跑背包出来的答案小于 ,否则它一定可以被替代。这就分出来A类了。
我们维护 与 分别表示考虑前 个和后 个物品,花费为至多 时得到的最大价值。枚举 ,比一下 与 即可。如果最大值还小于 ,那就是A类。
如何区别B类和C类捏?强制选 ,枚举 ,比一下 与 即可。如果能相等,那么就是B类了。否则不选它可以最大化价值,强制选它却不能,就是C。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = 1e3 + 5, M = 5e4 + 5;int n, m, p[N], v[N];ll ans = 0;signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; for(int i = 1;i <= n;i++) { cin >> p[i] >> v[i]; } vector<ll> f(M, -1e9); f[0] = 0; for(int i = 1;i <= n;i++) { for(int j = m;j >= p[i];j--) f[j] = max(f[j], f[j - p[i]] + v[i]); } for(int i = 0;i <= m;i++) ans = max(ans, f[i]); vector<ll> pre(M, -1e9); vector<vector<ll> > suf(N); pre[0] = 0; suf[n + 1].resize(m + 5); for(int i = 1;i <= m;i++) suf[n + 1][i] = 0; suf[n + 1][0] = 0; for(int i = n;i >= 1;i--) { suf[i] = suf[i + 1]; for(int j = m;j >= p[i];j--) suf[i][j] = max(suf[i][j], suf[i][j - p[i]] + v[i]); for(int j = 1;j <= m;j++) suf[i][j] = max(suf[i][j], suf[i][j - 1]); } for(int i = 1;i <= n;i++) { ll res = 0; for(int j = 0;j <= m;j++) res = max(res, pre[j] + suf[i + 1][m - j]); ll tres = 0; for(int j = 0;j <= m - p[i];j++) tres = max(tres, pre[j] + suf[i + 1][m - p[i] - j] + v[i]);
for(int j = m;j >= p[i];j--) pre[j] = max(pre[j], pre[j - p[i]] + v[i]); for(int j = 1;j <= m;j++) pre[j] = max(pre[j], pre[j - 1]); if(res == ans) { if(tres == ans) putchar('B'); else putchar('C'); } else if(res < ans) putchar('A'); } return 0;}G
场上没做掉,标记处理得不好。todo 吧。
觉得这篇文章怎么样?
点个赞,让更多人看到!

评论区