Codeforces Round #825 (Div. 2) D Equal Binary Subsequences
Equal Binary Subsequences
构造
赛中一直卡在 \(C2\),没看到这题
显然数字出现的次数为奇数的无解
考虑偶数的情况,可以将数字相邻两个组合在一起,\([2 * i + 1, 2 * i + 2]\)
-
如果两个都是 \(0\) 或者 \(1\),两个分到两边去就行了
-
如果两个是 \(01\) 或者 \(10\),我们可以通过右旋转的方式让他们变成第一种情况
间隔着选:第一个 \(01\) 或 \(10\) 选择数字 \(0\),第二个 \(01\) 或 \(10\) 选择数字 \(1\),如此选择 \(b\) 子序列,然后右旋转,必然可以使其变成第一种情况
因为第二种情况一定是偶数个,那右旋转获得的数字就一定是和当前选择的数字不同的那个
综上,数字出现的次数为偶数的情况,必有解
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
string s;
cin >> s;
int cnt = 0;
for(char now : s) cnt += now == '1';
if(cnt & 1) {cout << "-1\n"; continue;}
vector<int>ch;
int cur = '0';
for(int i=0; i<n; i++)
{
int now = i << 1, nex = i << 1 | 1;
if(s[now] == s[nex]) continue;
int way = now;
if(s[nex] == cur) way = nex;
cur ^= '1' ^ '0';
ch.push_back(way + 1);
}
cout << ch.size() << " ";
for(int now : ch) cout << now << " ";
cout << "\n";
for(int i=0; i<n; i++) cout << (i << 1 | 1) << " ";
cout << "\n";
}
return 0;
}