AtCoder Beginner Contest 444
个人题解
Nanami^2 Even in the rain.
2026年02月07日
预计阅读 7 分钟
1338 字
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); string s; cin >> s; if(s[0] == s[1] && s[1] == s[2] && s[0] == s[1]) { cout << "Yes" << endl; } else cout << "No" << 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, k;int calc(int x) { int res = 0; while(x) { res += x % 10; x /= 10; } return res;}signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> k; int ans = 0; for(int i = 1;i <= n;i++) { if(calc(i) == k) ans++; } cout << ans << endl; return 0;}C
C 比 D 难这一块。
赛时觉得一眼不可做,后来出题人补了一个条件:只进行了一次切割。
先排个序。
要么所有的数都参与配对,要么存在一部分数不参与配对。既然要所有都等长,那么这些不参与匹配的数一定就是相等的那个值,于是乎这些值一定是原序列的最大值。
所以,要么 匹配 ,所有数都要变成 。维护两个指针从两头扫一遍就行了。
对于第二种情况,如果 ,其中 为次大值,那么就对 中的数两两配对即可。
注意有很多 Corner Case。
#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, a[N];map<int, bool> mp;vector<int> ans;signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; for(int i = 1;i <= n;i++) { cin >> a[i]; } sort(a + 1, a + n + 1); int k = 0; if(n > 1) { k = a[1] + a[n]; int l = 2, r = n - 1; while(l <= r) { if(l == r) break; if(a[l] + a[r] != k) break; l++; r--; } if(l > r) ans.pb(k); } int p = n - 1; if(a[1] == a[n]) { ans.pb(a[n]); p = 0; } while(p > 1 && a[p] == a[n]) p--; if(p > 1 && a[1] + a[p] == a[n]) { int l = 2, r = p - 1; k = a[n]; while(l <= r) { if(l == r) break; if(a[l] + a[r] != k) break; l++; r--; } if(l > r) ans.pb(k); } sort(ans.begin(), ans.end()); for(auto x : ans) cout << x << " "; cout << endl; return 0;}D
小力推式子。
令
排序后随便二分即可。
问题在于如何处理这个输出形式。
搞一个string,预留足够多的空位,把数倒过来存。这样直接把贡献加到对应数位上,只考虑 的系数即可。把每一位拆开做,这部分的复杂度 。
#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];string ans;void add(int p, int x) { if(x == 0) return; if(ans[p] - '0' + x < 10) { ans[p] = ans[p] + x; return; } else { int t = (ans[p] - '0' + x) % 10; ans[p] = t + '0'; add(p + 1, 1); }}signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; for(int i = 1;i <= n;i++) { cin >> a[i]; m = max(m, a[i]); } sort(a + 1, a + n + 1); ans.resize(m + n); for(int i = 0;i <= m + n;i++) ans[i] = '0'; int mxp = 0; for(int j = 0;j < m;j++) { int cnt = n - (upper_bound(a + 1, a + n + 1, j) - a - 1); int i = j, x = cnt; while(x) { add(i, x % 10); x /= 10; mxp = max(mxp, i); i++; } } for(int i = mxp;~i;i--) { cout << ans[i]; } cout << endl; return 0;}E
身败名裂了属于是。
#include<bits/stdc++.h>using namespace std;using ll=long long;
int main(){ int n,d; cin >> n >> d; vector<int>a(n); for(auto&x:a)cin >> x;
ll ans=0; set<ll>s({(ll)-1e9,(ll)2e9}); // 显然我观察到了小区间不行会直接导致大区间不行,这就是标准的双指针模板,但是我干了啥啊草 int r=0; for(int l=0;l<n;l++){ while(r<n){ auto it=s.lower_bound(a[r]); if(*it-a[r]<d)break; it--; if(a[r]-*it<d)break; s.insert(a[r]); r++; } ans+=r-l; s.erase(a[l]); } cout << ans << endl;}F
todo.
觉得这篇文章怎么样?
点个赞,让更多人看到!

评论区