【暴力+剪枝】输出表演方案 Codeforces Round #545 (Div. 2) B. Circus
作者:互联网
Codeforces Round #545 (Div. 2) B. Circus
http://codeforces.com/contest/1138/problem/B
给你两行01串,长度均为n(n<=5000)
第一个串表示第i个人能否扮演小丑(1表示可以,0表示不可以)
第二个串表示第i个人能否扮演杂剧(1表示可以,0表示不可以)
保证n是偶数,让你输出n/2个编号
代表第一次上台
要求第一次上台的可以扮演小丑人数和第二次上台扮演杂剧人数相等,且每个人只能出场一次
直接n^4暴力
加上打剪枝
不会被卡
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x,y,sum;
} a[5005];
char s[5005];
int main()
{
int n;
cin>>n;
int clown=0,play=0,all_2=0,all_0=0;
scanf("%s",s+1);
for(int i=1; i<=n; i++)
{
a[i].x=s[i]-'0';
}
scanf("%s",s+1);
for(int i=1; i<=n; i++)
{
a[i].y=s[i]-'0';
}
for(int i=1; i<=n; i++)
{
a[i].sum=a[i].x+a[i].y;
if(a[i].sum==1)
{
if(a[i].x) clown++;
if(a[i].y) play++;
}
if(a[i].sum==2) all_2++;
if(a[i].sum==0) all_0++;
}
int h=n/2;
for(int i=0; i<=clown; i++)
{
if(i>h) break;
if((i+play+all_2+all_0)<h) continue;
for(int j=0; j<=play; j++)
{
if((i+j)>h) break;
if((i+j+all_2+all_0)<h) continue;
for(int k=0; k<=all_2; k++)
{
if((i+j+k)>h) break;
if((i+j+k+all_0)<h) continue;
for(int p=0; p<=all_0; p++)
{
if((i+j+k+p)>h) break;
if(i+j+k+p!=h) continue;
if((i+k)!=(play-j+all_2-k)) continue;
//cout<<i<<" "<<j<<" "<<k<<" "<<p<<endl;
int a1=0,b1=0,c1=0,d1=0;
for(int o=1; o<=n; o++)
{
if(a[o].x==1&&a[o].y==0&&a1!=i)
{
a1++;
printf("%d ",o);
}
}
for(int o=1; o<=n; o++)
{
if(a[o].x==0&&a[o].y==1&&b1!=j)
{
b1++;
printf("%d ",o);
}
}
for(int o=1; o<=n; o++)
{
if(a[o].sum==2&&c1!=k)
{
c1++;
printf("%d ",o);
}
}
for(int o=1; o<=n; o++)
{
if(a[o].sum==0&&d1!=p)
{
d1++;
printf("%d ",o);
}
}
cout<<endl;
return 0;
}
}
}
}
printf("-1\n");
return 0;
}
标签:剪枝,play,int,Circus,上台,Codeforces,break,扮演 来源: https://blog.csdn.net/qq_41037114/article/details/88365618