Codeforces Round #545 (Div. 2)B. Circus(思维)

题目链接:http://codeforces.com/contest/1138/problem/B

题意:给你两列01串,从第一列中挑出一些0和1,并且下标只能用一次,也就是在第一列挑下标为1的数第二列就不能用了,最终挑选n/2个数,并且使第一列1的个数和第二列相等,输出第一列挑选数的下标,如果不能输出-1。

思路:挑选第一列为1第二列为0的数相当于第一列+1,挑选第一列为0第二列为1的数相当于第二列-1,挑选第一列第二列都为1的相当于第二列-2,然后暴力枚举即可。

#include 
using namespace std;
typedef long long ll;
const int maxn = 100000;
int n;
char s[maxn + 10], t[maxn + 10];
vector 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())
			{
				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");
}

 

你可能感兴趣的:(【思维】)