Codeferce 1138B - Circus

题目的意思是给定两个01序列

第一个序列中如果a[i]为1,表示第i个人可以表演clown,0表示不能表演clown。

第二个序列中如果c[i]为1,表示第i个人可以表演acrobat,0表示不能表演acrobat。

总共两次表演,每次出场n/2个人,且满足表演过的不能再次出场,且第一次出场的可以表演clown的人的数量的必须等于第二次出场表演acrobat。

输出第一次出场的人的编号,无解输出-1

当时想了一会,没想出来,我越想越乱,看了题解后顿时明白了,题解也算是一种暴力吧

这其实就是一个解方程的过程,两个方程,4个未知量,同时知道这四个未知量的范围,那我们就可以枚举两个未知量,解剩下两个未知量,满足就输出。

a+b+c+d= n/2;

b+c+2d=nb+nd;

解出c = n - 2 * (a + b) - nb - nd + b;

  d = n / 2 - c - a - b;

暴力枚举a,b,然后解出c,d,判断满不满足,满足就输出

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> aa, bb, cc, dd;
const int N = 5e3 + 10;
int n,na,nb,nc,nd;
int a[N], c[N];
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        scanf("%1d", &a[i]);
    for (int i = 0; i < n; i++)
        scanf("%1d", &c[i]);
    for (int i = 0; i < n; i++)
    {
        if (a[i] == 0 && c[i] == 0)
            na++, aa.push_back(i+1);
        else if (a[i] == 0 && c[i] == 1)
            nb++, bb.push_back(i+1);
        else if (a[i] == 1 && c[i] == 0)
            nc++, cc.push_back(i+1);
        else
            nd++, dd.push_back(i+1);
    }
    for (int a = 0; a <= na; a++)
    {
        for (int b = 0; b <= nb; b++)
        {
            int c = n - 2 * (a + b) - nb - nd + b;
            if (c >= 0 && c <= nc)
            {
                int d = n / 2 - c - a - b;
                if (d >= 0 && d <= nd)
                {
                    //cout << a << b << c << d << endl;
                    for (int i = 0; i < a; i++)
                        printf("%d ", aa[i]);
                    for (int i = 0; i < b; i++)
                        printf("%d ", bb[i]);
                    for (int i = 0; i < c; i++)
                        printf("%d ", cc[i]);
                    for (int i = 0; i < d; i++)
                        printf("%d ", dd[i]);
                    printf("\n");
                    return 0;
                }

            }
        }
    }
    printf("-1\n");
    return 0;
}
posted @ 2019-03-10 14:12  TLE自动机  阅读(315)  评论(0编辑  收藏  举报