ACM 暑假集训题 Circus

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

 

题目:

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 (2n5000, n

is even) — the number of artists in the troupe.

The second line contains n

digits c1c2cn, 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 a1a2an, 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

.

example

    
    Input
4
0011
0101
Output
1 4
Input
6
000000
111111
Output
-1
Input
4
0011
1100
Output
4 3
Input
8
00100101
01111100
Output
1 2 3 6

Note

In the first example, one of the possible divisions into two performances is as follows: in the first performance artists 1 and 4 should take part. Then the number of artists in the first performance who can perform as clowns is equal to 1. And the number of artists in the second performance who can perform as acrobats is 1

as well.

In the second example, the division is not possible.

In the third example, one of the possible divisions is as follows: in the first performance artists 3

and 4 should take part. Then in the first performance there are 2 artists who can perform as clowns. And the number of artists in the second performance who can perform as acrobats is 2 as well.

思路

我用的dfs做的,后来一想,c(2500,5000)百分之二百会超时,后来我参考别人的代码,才知道是用数学逻辑推理可以做出来。

这些演员一共就四种情况:00,01,10,11,假设第一组的人数各为a1,a2,a3,a4,第二组的人数各为b1,b2,b3,b4。可以得到四种情况的演员的人数,二重循环枚举a3,a4的人数,可以得到b4的人数,b2=b+a4-b4,进而得到a2,a1的人数。

dfs错误代码:

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int c[5020],a[5020],sumc,suma,ans[5020],ansPos=0,n,ansNum=0,anss[5020];
char s1[5020],s2[5020];
bool dfs(int i);
int main()
{
    cin>>n;
    cin>>s1>>s2;
    
    for(int i=1;i<=n;i++)
    {
        c[i]=s1[i-1]-'0';
        a[i]=s2[i-1]-'0';
        if(a[i]==1)suma+=a[i];
    }
    int j;
    for(j=1;j<=n/2;j++)
    {
        dfs(j);
        if(ansNum==n/2)
        {
            for(int i=1;i<ansNum;i++)
            {
                cout<<ans[i]<<" ";
            }
            cout<<ans[ansNum]<<endl;
            break;
        }
    }
    if(j>n/2)
    {
        cout<<-1<<endl;
        return 0;
    }
    return 0;
}
bool dfs(int i)
{
    ansPos++;
    if(ansPos==n/2)
    {
        if(c[i]+sumc==suma-a[i]){
            ansNum=ansPos;
            for(int p=1;p<ansNum;p++)
            {
                anss[p]=ans[p];
            }
            anss[ansNum]=i;
            ans[ansPos]=i;
            return true;
        }
        else return false;
    }
    if(c[i]+sumc>=suma-a[i])return false;
    sumc+=c[i];
    suma-=a[i];
    ans[ansPos]=i;
    for(int j=1;j<=n-i;j++)
    {
        
        if(dfs(i+j))return true;
        else ans[ansPos--]=0;
    }
    ans[ansPos--]=0;
    sumc-=c[i];
    suma+=a[i];
}

 

AC代码:

#include<iostream>
using namespace std;
int n;
int amount[2][2];
char s1[5020],s2[5020];
int main()
{
    cin>>n;
    cin>>s1>>s2;
    for(int i=0;i<n;i++)
    {
        amount[s1[i]-'0'][s2[i]-'0']++;
    }
    for(int a3=0;a3<=amount[1][0];a3++)
    {
        for(int a4=0;a4<=amount[1][1];a4++)
        {
            int b4=amount[1][1]-a4;
            int b2=a3+a4-b4;
            if(b2<0||b2>amount[0][1])continue;
            int b3=amount[1][0]-a3;
            int b1=n/2-b2-b3-b4;
            if(b1<0||b1>amount[0][0])continue;
            amount[0][0]-=b1;amount[0][1]-=b2;amount[1][0]-=b3;amount[1][1]-=b4;
            for(int i=0;i<n;i++)
            {
                if(amount[s1[i]-'0'][s2[i]-'0']>0)
                {
                    cout<<i+1<<" ";
                    amount[s1[i]-'0'][s2[i]-'0']--;
                }
            }
            return 0;
        }
    }
    cout<<-1;
    return 0;
} 

 

 

posted @ 2019-07-25 11:36  小小笼包包  Views(157)  Comments(0)    收藏  举报