總體情況
A - 11/22 String
題目描述
本問題中 11/22 字串的定義與問題 C 和 E 中的定義相同。
當字串 \(T\) 滿足以下所有條件時,我們稱它為11/22 字串:
- \(|T|\) 是奇數。這裡, \(|T|\) 表示 \(T\) 的長度。
- 從 \(1\) 到 \((\frac{|T|+1}{2} - 1)\) 的字元都是 "1"。
- \((\frac{|T|+1}{2})\) -th字元是
/
。 - \((\frac{|T|+1}{2} + 1)\) -th到 \(|T|\) -th字元都是 "2"。
例如,11/22
、111/222
和/
是 11/22 字串,但1122
、1/222
、11/222
、22/11
和/2/2/211
則不是。
給定長度為 \(N\) 的字串 \(S\) 由 1
、2
和 /
組成,判斷 \(S\) 是否是 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
題目描述
當且僅當字串 \(T\) 滿足以下三個條件時,它才被稱為 1122 字串:
- \(\lvert T \rvert\) 是偶數。這裡, \(\lvert T \rvert\) 表示 \(T\) 的長度。
- 對於每個滿足 \(1\leq i\leq \frac{|T|}{2}\) 條件的整數 \(i\) 來說, \(T\) 的 \((2i-1)\) -th 字元和 \(2i\) -th 字元是相等的。
- 每個字元在 \(T\) 中出現的次數正好是 0 或 2。也就是說, \(T\) 中包含的每個字元在 \(T\) 中恰好出現兩次。
給定一個由小寫英文字母組成的字串 \(S\) ,如果 \(S\) 是一個 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 中的定義相同。
滿足以下所有條件的字串 \(T\) 稱為 11/22 字串:
- \(|T|\) 是奇數。這裡, \(|T|\) 表示 \(T\) 的長度。
- 從 \(1\) 到 \((\frac{|T|+1}{2} - 1)\) 的字元都是 "1"。
- \((\frac{|T|+1}{2})\) -th字元是
/
。 - 從 \((\frac{|T|+1}{2} + 1)\) 到 \(|T|\) 的字元都是 "2"。
例如,11/22
、111/222
和/
是 11/22 字串,但1122
、1/222
、11/222
、22/11
和/2/2/211
則不是。
給你一個長度為 \(N\) 的字串 \(S\) ,它由 1
、2
和 /
組成,其中 \(S\) 包含至少一個 /
。
請找出長度為 11/22 的 \(S\) 的(連續)子串的最大長度。
思路分析
列舉每一個 /
字元,按照順序暴力找就行。
程式碼
// 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
題目描述
一個由正整數(可能為空)組成的序列 \(X = (X_1, X_2, \ldots)\) 當且僅當它滿足以下三個條件時,才被稱為1122 序列:(1122 序列的定義與問題 F 中的定義相同)。
- \(\lvert X \rvert\) 是偶數。這裡, \(\lvert X \rvert\) 表示 \(X\) 的長度。
- 對於滿足 \(1\leq i\leq \frac{|X|}{2}\) 的每個整數 \(i\) , \(X_{2i-1}\) 和 \(X_{2i}\) 都相等。
- 每個正整數要麼完全不出現在 \(X\) 中,要麼正好出現兩次。也就是說, \(X\) 中包含的每個正整數在 \(X\) 中恰好出現兩次。
給定長度為 \(N\) 的由正整陣列成的序列 \(A = (A_1, A_2, \ldots, A_N)\) ,列印 \(A\) 的一個 (連續)子陣列 的最大長度,該陣列是一個 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 中的定義相同。
當字串 \(T\) 滿足以下所有條件時,我們稱它為11/22 字串:
- \(|T|\) 是奇數。這裡, \(|T|\) 表示 \(T\) 的長度。
- 從 \(1\) 到 \((\frac{|T|+1}{2} - 1)\) 的字元都是 "1"。
- \((\frac{|T|+1}{2})\) -th字元是
/
。 - \((\frac{|T|+1}{2} + 1)\) -th到 \(|T|\) -th字元都是 "2"。
例如,11/22
、111/222
和/
是 11/22 字串,但1122
、1/222
、11/222
、22/11
和/2/2/211
則不是。
給定長度為 \(N\) 的字串 \(S\) ,由1
、2
和/
組成,處理 \(Q\) 個查詢。
每個查詢提供兩個整數 \(L\) 和 \(R\) 。假設 \(T\) 是 \(S\) 中從 \(L\) -th 到 \(R\) -th 字元的(連續)子串。求 \(T\) 的(不一定連續)子串的最大長度,該子串是一個 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;
}