circus
题意:给你两列01串,从第一列中挑出一些0和1,并且下标只能用一次,也就是在第一列挑下标为1的数第二列就不能用了,最终挑选n/2个数,并且使第一列1的个数和第二列相等,输出第一列挑选数的下标,如果不能输出-1。
思路:挑选第一列为1第二列为0的数相当于第一列+1,挑选第一列为0第二列为1的数相当于第二列-1,挑选第一列第二列都为1的相当于第二列-2,然后暴力枚举即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000;
int n;
char s[maxn + 10], t[maxn + 10];
vector<int> a, b, c, d;
int main()
{
scanf("%d", &n);
scanf("%s%s", s + 1, t + 1);
for(int i = 1; i <= n; ++i)
if(s[i] == '0' && t[i] == '0') a.push_back(i);
else if(s[i] == '1' && t[i] == '0') b.push_back(i);
else if(s[i] == '0' && t[i] == '1') c.push_back(i);
else if(s[i] == '1' && t[i] == '1') d.push_back(i);
for(int i = 0; i <= (int)b.size(); ++i)
for(int j = 0; j <= (int)d.size(); ++j)
{
int s = (int)c.size() + (int)d.size() - i - 2 * j;
//第二列多出的1的个数
if(s >= 0 && s <= (int)c.size())//若s等于0,则第一排和第二排的1的个数相等
//若s>0,将下排的1删去
{
int all = i + s + j;
int k = n / 2 - all; //不够n/2用0,0补齐
if (k >= 0 && k <= (int)a.size())
{
for (int p = 0; p < k; ++p) printf("%d ", a[p]);
for (int p = 0; p < i; ++p) printf("%d ", b[p]);
for (int p = 0; p < s; ++p) printf("%d ", c[p]);
for (int p = 0; p < j; ++p) printf("%d ", d[p]);
return 0;
}
}
}
printf("-1");
}