题目链接:https://codeforces.com/contest/1138/problem/B
题意:有四种类型的艺术家(x,y), (0,0) ,(0,1) , (1,0) , (1,1) ,x=1表示这位艺术家可以扮演小丑,y=1表示这位艺术家可以耍杂技,先要在n个艺术家中挑选 一半的艺术家表演,满足这些艺术家能扮演小丑的数量与没被挑选的艺术家中能耍杂技的数量要相等,输出挑选的艺术家编号。
题解:我们设有na个(0,0)艺术家,nb个(0,1)艺术家,nc个(1, 0)艺术家,nd个(1,1)艺术家。
a,b,c,d为我们要挑选艺术家的数量,那么a+b+c+d=n/2。
c+d=nb-b+nd-d。
两个方程,四个未知数,我们可以枚举两个未知数b与c。
思考:一开始看到这题,没有什么思路,以为是dp,然后就.....,以后看到n=1000的,马上要想到n^2做法,n=100,要想到n^3做法。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
char op[5100],op2[5100];
int na,nb,nc,nd;
int main()
{
int n;
scanf("%d",&n);
scanf("%s%s",op,op2);
// printf("%s\n%s\n",op,op2);
for(int i=0;i<n;i++)
{
if(op[i]=='0'&&op2[i]=='0') na++;
else if(op[i]=='0'&&op2[i]=='1') nb++;
else if(op[i]=='1'&&op2[i]=='0') nc++;
else if(op[i]=='1'&&op2[i]=='1') nd++;
}
for(int b=0;b<=nb;b++)
{
for(int c=0;c<=nc;c++)
{
int d=(nb+nd-b-c)/2;
int a=n/2-b-c-d;
if(d<0||d>nd||a<0||a>na) continue;
if((b+c+2*d)==(nb+nd)){
int sa=a,sb=b,sc=c,sd=d;
// printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
for(int i=0;i<n;i++)
{
if(op[i]=='0'&&op2[i]=='0'&&sa) sa--,printf("%d ",i+1);
else if(op[i]=='0'&&op2[i]=='1'&&sb) sb--,printf("%d ",i+1);
else if(op[i]=='1'&&op2[i]=='0'&&sc) sc--,printf("%d ",i+1);
else if(op[i]=='1'&&op2[i]=='1'&&sd) sd--,printf("%d ",i+1);
}
puts("");
return 0;
}
}
}
puts("-1");
return 0;
}