其他分享
首页 > 其他分享> > 【暴力+剪枝】输出表演方案 Codeforces Round #545 (Div. 2) B. Circus

【暴力+剪枝】输出表演方案 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