Codeforces Round #712 (Div. 2) (A-D)
Codeforces Round #712 (Div. 2)
A. Déjà Vu
题意
给一个字符串,可以在任意地方插入一个字符 a ,使其不是回文串
sol
显然当字符串全由a组成的话,不论怎么插,都是回文的,
否则只需判断如果插在第一位构成回文的话,就将其插在末尾,不构成的话直接输出
code
bool check(string s) {
int l = 0;
int r = s.size() - 1;
while(l <= r) {
if(s[l] != s[r]) {
return false;
}
l++; r--;
}
return true;
}
void solve() {
string s;
cin >> s;
if(count(s.begin(),s.end(),'a') == s.size()) {
cout << "NO" << "\n";
return;
}
cout << "YES" << "\n";
if(check("a"+s)) {
cout << (s + "a") << "\n";
}
else {
cout << ("a" + s) << "\n";
}
}
B. Flip the Bits
题意
给两个01串a和b,可以对a执行操作:
- 选择一段a的前缀并且前缀中包含相同数量的0和1,将其反转
问是否可以在若干次操作后得到b串
sol
考虑将每个可以进行操作(即前缀中包含相同数量的0和1)的位置存起来,然后从后往前进行操作
因为可以操作无数次,所以每次操作的区间可以缩短为前一个符合条件的位置到当前,
如果这段区间的数都相同或者都不相同,那么就表示这段区间成立,判断过程中如果有不成立的直接输出no
注意可以操作的位置不是最后一位的话需要判断后面的区间是否相等,因为后面的区间无法操作
code
int n,m;
int sum[maxn],sum2[maxn],flag;
char s1[maxn],s2[maxn];
bool check(int l,int r) {
for(int i = l; i <= r; i++) {
if(!flag) {
if(s1[i] != s2[i])
return false;
}
else {
if(s1[i] == s2[i])
return false;
}
}
return true;
}
std::vector<int> p;
void solve() {
cin >> n;
cin >> s1+1;
cin >> s2+1;
flag = 0;
p.clear();
p.PB(0);
CLR(sum,0);
for(int i = 1; i <= n; i++) {
sum[i] = sum[i-1] + (s1[i] == '1');
if(sum[i] * 2 == i) p.PB(i);
}
for(int i = p.back()+1; i <= n; i++) {
if(s1[i] != s2[i]) {
cout << "NO" << "\n";
return;
}
}
for(int i = p.size()-1; i >= 1; i--) {
if(!check(p[i-1]+1,p[i])) {
flag ^= 1;
}
if(!check(p[i-1]+1,p[i])) {
cout << "NO" << "\n";
return;
}
}
cout << "YES" << "\n";
}
C. Balance the Bits
题意
略
sol
可以将0和1的位置存起来,特判下数组中个数是否为奇数以及原数组头和尾是否相等 .然后分别遍历
对于1,从左右两边遍历, 左边给左括号,右边右括号
对于0,根据奇偶性给左右或右左
code
char s[maxn],a[maxn],b[maxn];
void solve() {
cin >> n;
cin >> s+1;
std::vector<int> cnt_1,cnt_0;
// std::vector<char> a,b;
for(int i = 1; i <= n; i++) {
if(s[i] == '1') {
cnt_1.PB(i);
}
else cnt_0.PB(i);
}
// cout << cnt_1[0] << "\n";
if(s[1] != '1' || s[n] != '1' || cnt_1.size() & 1) {
cout << "NO" << "\n";
return;
}
int r = cnt_1.size() - 1;
for(int l = 0; l < r; l++,r--) {
a[cnt_1[l]] = b[cnt_1[l]] = '(';
a[cnt_1[r]] = b[cnt_1[r]] = ')';
}
for(int i = 0; i < cnt_0.size(); i++) {
if(i & 1) {
cout << cnt_0[i] << "\n";
a[cnt_0[i]] = '(';
b[cnt_0[i]] = ')';
}
else {
a[cnt_0[i]] = ')';
b[cnt_0[i]] = '(';
}
}
cout << "YES" << "\n";
for(int i = 1; i <= n; i++) {
cout << a[i] ;
}
cout << "\n";
for(int i = 1; i <= n; i++) {
cout << b[i] ;
}
cout << "\n";
}
D. 3-Coloring
题意
略
sol
考虑国际象棋棋盘,将1填进黑格,将2填进白格.
对于Alice 给的某个数,如果等于1,就给白格填2,等于2的话,就给黑格填1
如果某一种方格填完的话,就填3即可
code
int n,m;
void print(int a,int x,int y) {
cout << a << " " << x << " " << y << "\n";
cout.flush();
}
int main() {
cin >> n;
std::vector<pii> a,b;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if((i + j) & 1) {
a.PB(make_pair(i,j));
}
else {
b.PB(make_pair(i,j));
}
}
}
for(int i = 1; i <= n*n; i++) {
int x;
cin >> x;
if(x != 1 && !a.empty()) {
print(1,a.back().first,a.back().second);
a.pop_back();
}
else if(x != 2 && !b.empty()) {
print(2,b.back().first,b.back().second);
b.pop_back();
}
else if(a.size()) {
print(3,a.back().first,a.back().second);
a.pop_back();
}
else if(b.size()) {
print(3,b.back().first,b.back().second);
b.pop_back();
}
}
return 0;
}