AtCoder Beginner Contest 381 题解
总体情况
A - 11/22 String
题目描述
本问题中 11/22 字符串的定义与问题 C 和 E 中的定义相同。
当字符串 满足以下所有条件时,我们称它为11/22 字符串:
- 是奇数。这里, 表示 的长度。
- 从 到 的字符都是 "1"。
- -th字符是
/
。 - -th到 -th字符都是 "2"。
例如,11/22
、111/222
和/
是 11/22 字符串,但1122
、1/222
、11/222
、22/11
和/2/2/211
则不是。
给定长度为 的字符串 由 1
、2
和 /
组成,判断 是否是 11/22 字符串。
思路分析
直接模拟即可。
代码
// Problem: A - 11/22 String // Contest: AtCoder - AtCoder Beginner Contest 381 // URL: https://atcoder.jp/contests/abc381/tasks/abc381_a // Memory Limit: 1024 MB // Time Limit: 2000 ms #include<bits/stdc++.h> using namespace std; #define endl '\n' //#define int long long namespace gtx{ // Fast IO void read(int &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');} void write(char x){putchar(x);} void write(int x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(int x,char y){write(x);write(y);} #ifndef int void read(long long &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void write(long long x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(long long x,char y){write(x);write(y);} #endif signed main(){ int n; read(n); if(n&1){ for(int i = 1;i<=n/2;i++){ char tmp; read(tmp); if(tmp!='1') return puts("No"),0; } char tmp;read(tmp); if(tmp!='/') return puts("No"),0; for(int i = 1;i<=n/2;i++){ char tmp; read(tmp); if(tmp!='2') return puts("No"),0; } puts("Yes"); }else puts("No"); return 0; } } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); // ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int T = 1; // gtx::read(T); while(T--) gtx::main(); return 0; }
B - 1122 String
题目描述
当且仅当字符串 满足以下三个条件时,它才被称为 1122 字符串:
- 是偶数。这里, 表示 的长度。
- 对于每个满足 条件的整数 来说, 的 -th 字符和 -th 字符是相等的。
- 每个字符在 中出现的次数正好是 0 或 2。也就是说, 中包含的每个字符在 中恰好出现两次。
给定一个由小写英文字母组成的字符串 ,如果 是一个 1122 字符串,则打印 "是",否则打印 "否"。
思路分析
也是直接按照题意模拟即可。
代码
// Problem: B - 1122 String // Contest: AtCoder - AtCoder Beginner Contest 381 // URL: https://atcoder.jp/contests/abc381/tasks/abc381_b // Memory Limit: 1024 MB // Time Limit: 2000 ms #include<bits/stdc++.h> using namespace std; #define endl '\n' //#define int long long namespace gtx{ // Fast IO void read(int &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');} void write(char x){putchar(x);} void write(int x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(int x,char y){write(x);write(y);} #ifndef int void read(long long &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void write(long long x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(long long x,char y){write(x);write(y);} #endif signed main(){ map<char,int> mp; string s; cin >> s; if(s.size()&1) return puts("No"),0; for(int i = 1;i<=(int)s.size()/2;i++){ if(s[2*i-2]!=s[2*i-1]) return puts("No"),0; } for(char i:s) mp[i]++; for(auto tmp:mp) if(tmp.second!=2) return puts("No"),0; puts("Yes"); return 0; } } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); // ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int T = 1; // gtx::read(T); while(T--) gtx::main(); return 0; }
C - 11/22 Substring
题目描述
本问题中 11/22 字符串的定义与问题 A 和 E 中的定义相同。
满足以下所有条件的字符串 称为 11/22 字符串:
- 是奇数。这里, 表示 的长度。
- 从 到 的字符都是 "1"。
- -th字符是
/
。 - 从 到 的字符都是 "2"。
例如,11/22
、111/222
和/
是 11/22 字符串,但1122
、1/222
、11/222
、22/11
和/2/2/211
则不是。
给你一个长度为 的字符串 ,它由 1
、2
和 /
组成,其中 包含至少一个 /
。
请找出长度为 11/22 的 的(连续)子串的最大长度。
思路分析
枚举每一个 /
字符,按照顺序暴力找就行。
代码
// Problem: C - 11/22 Substring // Contest: AtCoder - AtCoder Beginner Contest 381 // URL: https://atcoder.jp/contests/abc381/tasks/abc381_c // Memory Limit: 1024 MB // Time Limit: 2000 ms #include<bits/stdc++.h> using namespace std; #define endl '\n' //#define int long long namespace gtx{ // Fast IO void read(int &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');} void write(char x){putchar(x);} void write(int x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(int x,char y){write(x);write(y);} #ifndef int void read(long long &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void write(long long x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(long long x,char y){write(x);write(y);} #endif signed main(){ int n; cin>>n; bool tmp=0; // vector<pair<int,int>> v; int ans = 0; string s; cin >>s; vector<int> v; for(int i = 0;i<s.size();i++){ if(s[i]=='/') v.push_back(i); } for(int j:v){ int cnt1 = 0; for(int i = j-1;~i;i--){ if(s[i]!='1') break; cnt1++; } int cnt2 = 0; for(int i = j+1;i<s.size();i++){ if(s[i]!='2') break; cnt2++; } ans = max(ans,min(cnt1,cnt2)); } write(1+2*ans); return 0; } } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); // ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int T = 1; // gtx::read(T); while(T--) gtx::main(); return 0; }
D - 1122 Substring
题目描述
一个由正整数(可能为空)组成的序列 当且仅当它满足以下三个条件时,才被称为1122 序列:(1122 序列的定义与问题 F 中的定义相同)。
- 是偶数。这里, 表示 的长度。
- 对于满足 的每个整数 , 和 都相等。
- 每个正整数要么完全不出现在 中,要么正好出现两次。也就是说, 中包含的每个正整数在 中恰好出现两次。
给定长度为 的由正整数组成的序列 ,打印 的一个 (连续)子数组 的最大长度,该数组是一个 1122 序列。
思路分析
直接双指针模拟即可。
代码
// Problem: D - 1122 Substring // Contest: AtCoder - AtCoder Beginner Contest 381 // URL: https://atcoder.jp/contests/abc381/tasks/abc381_d // Memory Limit: 1024 MB // Time Limit: 2000 ms #include<bits/stdc++.h> using namespace std; #define endl '\n' //#define int long long namespace gtx{ // Fast IO void read(int &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');} void write(char x){putchar(x);} void write(int x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(int x,char y){write(x);write(y);} #ifndef int void read(long long &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void write(long long x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(long long x,char y){write(x);write(y);} #endif const int MAXN = 2e5+10; int n,a[MAXN]; signed main(){ read(n); map<int,int> mp; for(int i = 1;i<=n;i++) read(a[i]); int r = 1; int ans = 0; bool tmp = 0; for(int l = 1;l<=n;l++){ mp[a[l-1]] = 0; if(a[l]==a[l+1]) ans = max(ans,2); if(a[l]==a[l+1]&&a[l+2]!=a[l]){ if(tmp) r = l; while(r<=n){ if(a[r]==a[r+1]&&mp[a[r]]!=2){ mp[a[r]] = 2; r+=2; }else break; } ans = max(ans,r-l); l++; tmp=0; }else tmp=1; } write(ans); return 0; } } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); // ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int T = 1; // gtx::read(T); while(T--) gtx::main(); return 0; }
E - 11/22 Subsequence
题目描述
本问题中 11/22 字符串的定义与问题 A 和 C 中的定义相同。
当字符串 满足以下所有条件时,我们称它为11/22 字符串:
- 是奇数。这里, 表示 的长度。
- 从 到 的字符都是 "1"。
- -th字符是
/
。 - -th到 -th字符都是 "2"。
例如,11/22
、111/222
和/
是 11/22 字符串,但1122
、1/222
、11/222
、22/11
和/2/2/211
则不是。
给定长度为 的字符串 ,由1
、2
和/
组成,处理 个查询。
每个查询提供两个整数 和 。假设 是 中从 -th 到 -th 字符的(连续)子串。求 的(不一定连续)子串的最大长度,该子串是一个 11/22 字符串。如果不存在这样的子序列,则打印0
。
思路分析
对于给定一个位置,它是 /
,那么他的答案明显是前面 1
的个数与后面 2
的个数的较小值。
观察这个式子,前面 1
的个数上升,后面 2
的个数下降,所以他们的较小值一定是一个单峰函数,直接使用 三分法。(由于本人的三分写的很逆天,所以求出来的一定是在他的上下 1000 个以内……)
代码
// Problem: E - 11/22 Subsequence // Contest: AtCoder - AtCoder Beginner Contest 381 // URL: https://atcoder.jp/contests/abc381/tasks/abc381_e // Memory Limit: 1024 MB // Time Limit: 3000 ms #include<bits/stdc++.h> using namespace std; #define endl '\n' //#define int long long namespace gtx{ // Fast IO void read(int &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');} void write(char x){putchar(x);} void write(int x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(int x,char y){write(x);write(y);} #ifndef int void read(long long &x){ x = 0;int h = 1;char tmp; do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp)); while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar(); x*=h; } void write(long long x){ if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0; do{st[++tot]=x%10,x/=10;} while(x); while(tot){putchar(st[tot--]+'0');} } void write(long long x,char y){write(x);write(y);} #endif const int MAXN = 1e5+10; int n,q; vector<int> v; char a[MAXN]; int qz1[MAXN],qz2[MAXN]; int calc(int l,int r,int u){ return 2*min(qz1[u]-qz1[l-1],qz2[r]-qz2[u-1])+1; } signed main(){ read(n);read(q); for(int i = 1;i<=n;i++){ read(a[i]); qz1[i] = qz1[i-1]; qz2[i] = qz2[i-1]; if(a[i]=='1') qz1[i]++; if(a[i]=='2') qz2[i]++; if(a[i]=='/') v.push_back(i); } for(int i = 1;i<=q;i++){ int l,r; read(l);read(r); auto tmp = lower_bound(v.begin(),v.end(),l); if(tmp==v.end()){ puts("0"); continue; } auto end = upper_bound(v.begin(),v.end(),r); if(end==v.begin()){ puts("0"); continue; } --end; if((end-v.begin())<(tmp-v.begin())){ puts("0"); continue; } auto ls = tmp; auto rs = end; int ans = 1; while(rs-ls>2){ auto lmid = ls+(int)(rs-ls)/3; auto rmid = ls+2*(int)(rs-ls)/3; if(calc(l,r,*lmid)<calc(l,r,*rmid)) ls = lmid; else rs = rmid; } for(auto i = max(tmp,ls-min(1000,(int)(ls-v.begin())));i<=min(end,ls+min(1000,(int)(v.end()-ls-1)));i++){ ans = max(ans,calc(l,r,*i)); } write(ans,endl); } return 0; } } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); // ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int T = 1; // gtx::read(T); while(T--) gtx::main(); return 0; }
本文作者:辜铜星
本文链接:https://www.cnblogs.com/gutongxing/p/18563810
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步