AtCoder Beginner Contest 442
个人题解
Nanami^2 Even in the rain.
2026年01月25日
预计阅读 7 分钟
1504 字
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;}string s;signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> s; int ans = 0; for(auto x : s) if(x == 'i' || x == 'j') ans++; cout << ans << endl; 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, c, p;signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; while(n--) { int type; cin >> type; if(type == 1) c++; else if(type == 2 && c > 0) c--; else if(type == 3) { p ^= 1; } if(c >= 3 && p) cout << "Yes" << endl; else cout << "No" << 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 = 2e5 + 5;int n, m, a[N];PII e[N];ll u;signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; u = n * (n - 1) / 2 - m; for(int i = 1;i <= m;i++) { cin >> e[i].fi >> e[i].se; a[e[i].fi]++; a[e[i].se]++; } for(int i = 1;i <= n;i++) { ll res = 1ll * (n - 1 - a[i]) * (n - 1 - a[i] - 1) * (n - 1 - a[i] - 2) / 6; cout << res << " "; } cout << endl; return 0;}D
懒得动脑子了,树状数组暴力维护,写得飞快跑得有点慢。
#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, a[N];struct BIT { int c[N]; void add(int x, int d) { for(int i = x;i <= n;i += (i & -i)) c[i] += d; } int query(int x) { if(x == 0) return 0; ll res = 0; for(int i = x;i;i -= (i & -i)) res += c[i]; return res; }} T;signed main() { // ios::sync_with_stdio(0); // cin.tie(0); // cout.tie(0); cin >> n >> m; for(int i = 1;i <= n;i++) { cin >> a[i]; T.add(i, a[i]); } while(m--) { int type; cin >> type; if(type == 1) { int i; cin >> i; T.add(i, -a[i]); T.add(i + 1, -a[i + 1]); swap(a[i], a[i + 1]); T.add(i, a[i]); T.add(i + 1, a[i + 1]); } else { int l, r; cin >> l >> r; cout << T.query(r) - T.query(l - 1) << endl; } } return 0;}E
场上我选择了求极角结果被卡,估计改成比斜率就行了。
F
这题挺有意思的。
先进行一些基本的观察:
- 如果 为白色,那么以 为左上角, 为右下角的矩形都必须是白色。
- 对于一个合法的矩形,从上到下每一行开头的白色点数量是单调不增的。否则一定与上一条矛盾。
也就是说我们要维护对这个不增的轮廓线。
设 为处理完了前 行,其中第 行的白色点数量为 的方案数。
显然有
其中 为把第 行搞成前 个格子是白色,后面是黑色的代价,是个定值且容易计算。
于是乎
发现转移是个后缀min的形式,维护一下 即可转移。
还有一种 DP 方法是设 为把以 为右下角的矩形搞合法的最小代价,其中 分别为白色/黑色,这个也能做,但是维护的东西很麻烦,主要是丢掉了轮廓线的信息。而且你确定了一行的白色块延伸到哪里,这一行就确定了,状态信息是不够明显的。
#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 = 5e3 + 5;int n, cnt[N][N];string s[N];signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; for(int i = 1;i <= n;i++) { cin >> s[i]; s[i] = " " + s[i]; } for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { cnt[i][j] = cnt[i][j - 1] + (s[i][j] == '.'); } } vector<vector<int> > f(n + 5, vector<int>(n + 5, 0x3f3f3f)); for(int i = 0;i <= n;i++) f[0][i] = 0; for(int i = 1;i <= n;i++) { for(int j = 0;j <= n;j++) { f[i][j] = f[i - 1][j] + j - cnt[i][j] + cnt[i][n] - cnt[i][j]; } for(int j = n - 1;~j;j--) f[i][j] = min(f[i][j], f[i][j + 1]); } cout << f[n][0] << endl; return 0;}G
没做捏。
觉得这篇文章怎么样?
点个赞,让更多人看到!

评论区