Codeforces Global Round 20 [B~D]
链接:contest link
B.I love AAAB
题目
如果一个字符串长度大于等于 \(2\) 且最后一个字符为 B
,其他字符都为 A
,那么称这个字符串是 好 的
给定一个初始为空串的字符串 \(s_1\) ,可以执行任意次以下操作:
- 在 \(s_1\) 的任意位置插入一个好的字符串
给定一个字符串 \(s_2\) ,判断能否通过操作使 \(s_1\) 变为 \(s_2\)
分析
容易发现好串的 A
个数大于等于 B
的个数,所以如果 \(s_2\) 可以由好串组成,对于它的任意子串 \(s_1[1\cdots i]\) 满足 A
个数大于等于 B
的个数,且 \(s_1\) 的最后一个字符一定为 B
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while(t--) {
string s;
int cnt = 0;
cin >> s;
bool fnd = false;
for(int i = 0; i < (int)s.size(); i++) {
if(s[i] == 'A')
cnt++;
else
cnt--;
if(cnt < 0) {
cout << "NO" << endl;
fnd = true;
break;
}
}
if(!fnd)
cout << (s[s.size() - 1] == 'B' ? "YES" : "NO") << endl;
}
return 0;
}
C.Unequal Array
题目
给定一个长度为 \(n\) 的数组 \(a\) ,一个数组的 equality 定义为满足 \(a_i=a_{i+1}\) 的 \(i\) 的个数,可以执行如下操作:
- 选定两个整数 \(i,x\) 使 \(a_i=a_{i+1}=x\)
求使 \(a\) 的 equality 小于等于 \(1\) 的最小操作数
分析
设 \(l\) 是满足 \(a_i=a_{i-1}\) 的最小的 \(i\) , \(r\) 是最大的 \(i\) ,可以发现如果 \(r-l\not= 1\) 那么 \(a\) 的 equality 大于等于 \(2\) ,在执行操作 \(l,l+1,\cdots,r-3,r-2\) 后 equality 变为 \(1\) ,所以最小操作数为 \(r-1-l\) 。如果 \(r-l=1\) ,那么最小操作数为 \(1\)
代码
#include<bits/stdc++.h>
using namespace std;
int a[200000 + 5];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while(t--) {
int n, st = -1, en = -1;
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int i = 2; i <= n; i++) {
if(a[i] == a[i - 1]) {
st = i;
break;
}
}
for(int i = n; i >= 2; i--) {
if(a[i] == a[i - 1]) {
en = i - 1;
break;
}
}
if(st == -1 || en < st)
cout << 0 << endl;
else
cout << (en - st == 0 ? 1 : en - st) << endl;
}
return 0;
}
D.Cyclic Rotation
题目
给定一个长度为 \(n\) 的数组 \(a\) ,如果 \(a_l=a_r\) ,可以执行操作 \(a[l\cdots r]=\{a_{l+1},a_{l+2},\cdots,a_r,a_l\}\)
给定另一个数组 \(b\) ,判断 \(a\) 能否经过多次操作变成 \(b\)
分析
考虑反向操作,即对于 \(b\) 中相邻的两个元素 \(b_{i-1},b_i\) 我们可以把 \(b_i\) 放到 \(i-1\) 前的任意位置
用双指针,若现在有 \(a_l,b_r\) 要使 \(a_l\) 变为 \(b_r\)
若 \(a_l=b_r\) 那么 \(l+1,r+1\)
否则我们希望移动 \(l,r\) 中的一个,如果两者都无法移动,则无法匹配输出 NO
用一个 map<int, int> cnt
来记录匹配不成功的 \(a_l\) ,如果 \(b_{r-1}=b_r\) 那么可以消去一个 \(a_l\) ,如果不可以,那么把 \(a_l\) 加入 cnt
,记为匹配不成功,等待后面的 \(b_r\) 消去
代码
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 + 5;
int a[MAX_N], b[MAX_N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int i = 1; i <= n; i++)
cin >> b[i];
map<int, int> cnt;
int l = 1, r = 1;
bool flag = true;
while(r <= n) {
if(l <= n && a[l] == b[r]) {
l++;
r++;
} else {
if(cnt[b[r]] && b[r] == b[r - 1]) {
cnt[b[r]]--;
r++;
} else if(l <= n) {
cnt[a[l]]++;
l++;
} else {
flag = false;
break;
}
}
}
cout << (flag ? "YES" : "NO") << endl;
}
return 0;
}