【Atcoder训练记录】AtCoder Beginner Contest 381
训练情况

赛后反思
简单题A题做红温了,怒吃 6 罚时,C题双指针其实差不多想出来了,但是对于判断字符串合法其实可以只判断两个端点,不需要全部遍历,中途还想了二分做法(?),然而写到最后发现并没有二分单调性。
A题
记得判断字符串的长度必须是奇数,\(1 \sim \frac{n+1}{2}-1\) 是 1,\(\frac{n+1}/2\) 是 /,\(\frac{n+1}{2}+1 \sim n\) 是 2。满足上述所有条件就输出 Yes,否则输出 No。
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
int n;
char s[107];
cin>>n;
getchar();
for(int i = 1;i<=n;i++) cin>>s[i];
bool flag = true;
if(n%2==0) flag = false;
for(int i = 1;i<=(n+1)/2-1;i++) if(s[i] != '1') flag = false;
if(s[(n+1)/2] != '/') flag = false;
for(int i = (n+1)/2+1;i<=n;i++) if(s[i] != '2') flag = false;
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main(){
// int T; cin>>T; while(T--)
solve();
return 0;
}
B题
判断 \(2i - 1\) 和 \(2i\) 上的字符是否相同,字符串中每一个字母出现的次数均为 \(2\),满足上述所有条件输出 Yes,否则输出 No。
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
char s[107]; cin>>s+1;
int n = strlen(s+1);
bool flag = true;
if(n&1) flag = false;
for(int i = 1;i<=n/2;i++) if(s[2*i-1] != s[2*i]) flag = false;
map<char,int> cnt;
for(int i = 1;i<=n;i++) cnt[s[i]]++;
for(auto i:cnt) if(i.second != 2) flag = false;
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main(){
// int T; cin>>T; while(T--)
solve();
return 0;
}
C题
判断字符串中的满足 11/22 序列最长的子串长度,我们发现序列必须 / 在中间,所以我们考虑枚举 / 的位置再使用双指针往两边找,左边必须是 1,右边必须是 2,满足条件就 l--,r++ 扩大范围,最后答案取子串长度 \(r-l+1\) 的最大值。
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
int n; string s;
cin>>n>>s;
int ans = 0;
for(int i = 0;i<n;i++){
if(s[i] != '/') continue;
int l = i;
int r = i;
while(l-1>=0&&r-1<=n-1&&s[l-1] == '1'&&s[r+1]=='2'){
l--,r++;
}
ans = max(ans,r-l+1);
}
cout<<ans<<endl;
}
signed main(){
// int T; cin>>T; while(T--)
solve();
return 0;
}

浙公网安备 33010602011771号