Codeforces 517 #B

http://codeforces.com/contest/1072/problem/B

 

开始想的只有搜索,时间复杂度$O(4^n)$,明显有问题。

想了半个小时没有思路,然后想到了正难则反,就开始步入正轨。

题目给出了$a[ ]$和$b[ ]$数组,首先与处理,我们枚举每一种情况的$a[i]$和$b[i]$,然后枚举ans[i]表示当为$ans[i]$时下一个数可以填几,预处理完你会发现,有合法的数对的情况只有一种。

预处理时间复杂度$O(4^4)$

接下来我们可以枚举答案序列的第一位填啥,从而可以推出其他的数字填啥。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int f[5][5][5];
int n,a[100006],b[100006],ans[100006];
bool check()
{
    for(int i=2;i<=n;i++)
    {
        ans[i]=f[a[i]][b[i]][ans[i-1]];
        if(ans[i]==-1)return 0;
    }
    return 1;
}
int main()
{
    memset(f,-1,sizeof(f));
    for(int i=0;i<=3;i++)
    {
        for(int j=0;j<=3;j++)
        {
            for(int k=0;k<=3;k++)
            {
                for(int p=0;p<=3;p++)
                {
                    int x=p|k,y=p&k;
                    if(x==i&&y==j)f[i][j][k]=p;
                }
            }
        }
    }
    bool flag=0;
    scanf("%d",&n);
    for(int i=2;i<=n;i++)scanf("%d",&a[i]);
    for(int i=2;i<=n;i++)scanf("%d",&b[i]);
    for(int i=0;i<=3;i++)
    {
        ans[1]=i;
        if(check())
        {
            flag=1;
            break;
        }
    }
    if(!flag)printf("NO");
    else
    {
        printf("YES\n");
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    }
}

 

posted @ 2018-10-21 20:37  Manjusaka丶梦寒  阅读(166)  评论(2编辑  收藏  举报