【数学思维】【枚举】codeforces1138B Circus

B. Circus
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Polycarp is a head of a circus troupe. There are n — an even number — artists in the troupe. It is known whether the i-th artist can perform as a clown (if yes, then ci=1, otherwise ci=0), and whether they can perform as an acrobat (if yes, then ai=1, otherwise ai=0).

Split the artists into two performances in such a way that:

each artist plays in exactly one performance,
the number of artists in the two performances is equal (i.e. equal to n2),
the number of artists that can perform as clowns in the first performance is the same as the number of artists that can perform as acrobats in the second performance.
Input
The first line contains a single integer n (2≤n≤5000, n is even) — the number of artists in the troupe.

The second line contains n digits c1c2…cn, the i-th of which is equal to 1 if the i-th artist can perform as a clown, and 0 otherwise.

The third line contains n digits a1a2…an, the i-th of which is equal to 1, if the i-th artist can perform as an acrobat, and 0 otherwise.

Output
Print n2 distinct integers — the indices of the artists that should play in the first performance.

If there are multiple answers, print any.

If there is no solution, print a single integer −1.


 很好的一道题。做多了难题之后,不仅难题依旧不会,简单题也不会了QwQ。一开始想,这该不会是某种神奇的dp吧,想了半天dp方程没有得出结论。然后又想到一种方法,把原来的艺术家均分两等分,计算出第一个集合c的和以及第二个集合a的和,然后交换两个集合之间的元素,让这两个值的差为0,元素一共只有00,01,10,11四种,分类讨论交换的情况,但是发现凑出答案依旧不是一件很容易的事情。
 过了半小时有点自闭了。这才div2的第一题呀!想想最暴力的做法,无非是四重循环枚举在第一个集合里的四种元素的个数。等等!不用四重循环,如果第一重枚举11,第二种枚举10,那么就可以得到此时第一个集合c的和-第二个集合a的和,然后可以求解出01元素第二个集合的个数,进而求出01元素第一个集合的个数,最后用集合大小相等求出00集合的分配。这样看的话似乎只需要两层循环了。附上代码。

#include
#include
#include
using namespace std;

vector<int> E[4];
int n,a[5005],c[5005];
char s1[5005],s2[5005];

int main()
{
	scanf("%d%s%s",&n,s1+1,s2+1);
	for(int i=1;i<=n;i++)
		c[i]=s1[i]-'0';
	for(int i=1;i<=n;i++)
		a[i]=s2[i]-'0';
	for(int i=1;i<=n;i++)
		E[c[i]*2+a[i]].push_back(i);
	for(int i=0;i<=E[3].size();i++)
		for(int j=0,k,p,q,r;j<=E[2].size();j++)
		{
			k=i*2-E[3].size()+j;
			if(k<0||k>E[1].size())
				continue;
			k=E[1].size()-k;
			p=i+j+k;
			q=E[3].size()+E[2].size()+E[1].size()-p;
			if(abs(p-q)>E[0].size())
				continue;
			r=(E[0].size()-p+q)>>1;
			if(r*2!=E[0].size()-p+q)
				continue;
			for(int s=0;s<i;s++)
				printf("%d ",E[3][s]);
			for(int s=0;s<j;s++)
				printf("%d ",E[2][s]);
			for(int s=0;s<k;s++)
				printf("%d ",E[1][s]);
			for(int s=0;s<r;s++)
				printf("%d ",E[0][s]);
			return 0;
		}
	printf("-1");
	return 0;
}

你可能感兴趣的:(Codeforces,数学思维)