【CF1408A】 Circle Coloring 题解

原题链接

题意简介:
给你三个长度为n的数组 A,B,C ,现在我们要从 \(A_i,B_i,C_i\) 中挑一个数作为 \(D_i\) ,构造出一个 D 数组,使这个数组在头尾连接形成一个环后,相邻两个位置上的数各不相同。题目保证有解,只需要输出其中一个解就好。

题解:
对位置1,我们先选上某一个数,往后的其他位置我们则根据上一个数的情况判断三个数中的某个数能否选择,以及如果选择的话,上个数选的是哪个
最终,我们在位置n找到一个可以选择的数,往回推就可以了。

代码:

#include <cstdio>
#include <cstring>
const int N=105;
int A[N][3],n,f[N][3],ans[N];
int main(){
    int t; scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int o=0;o<3;o++) for(int i=1;i<=n;i++) scanf("%d",&A[i][o]);
        for(int o=0;o<3;o++){
            //枚举第一个位置选择的数
            memset(f,0,sizeof(f));
            //位置1不需要记录上一个数 但为了方便,我们将f[1][o]设为一个非0的数
            f[1][o]=1;
            //f[i][q]存这个数选q时上个数可以选什么
            for(int i=2;i<=n;i++){
                for(int p=0;p<3;p++){
                    //枚举上个数的选择
                    if(f[i-1][p]){
                        for(int q=0;q<3;q++) //枚举这个数的选择
                        if(A[i][q]!=A[i-1][p]) f[i][q]=p+1;
                    }
                }
            }
            //回推
            int end=0;
            for(int p=0;p<3;p++){
                if(f[n][p]&&A[n][p]!=A[1][o]) end=p+1;
                if(end) break;
            }
            if(!end) continue;
            ans[n]=A[n][end-1];
            for(int i=n-1;i>=1;i--){
                ans[i]=A[i][f[i+1][end-1]-1];
                end=f[i+1][end-1];
            }
            //if(ans[1]!=A[1][o]) printf("ERR\n");
            break;
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        putchar('\n');
    }
    return 0;
}
posted @ 2020-10-01 09:34  喵乖乖喵  阅读(183)  评论(0编辑  收藏  举报

膜拜众神

网安院技术部     ZZY大师     Xinyang 大佬     Wjyyy