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]); } }
除特别注明外,本站所有文章均为Manjusaka丶梦寒原创,转载请注明来自出处