• Fliptil_KEY


    Fliptil(fliptile.pas/c/cpp)

    【问题描述】

    约翰知道,那些高智力又快乐的奶牛产奶量特别高。所以他做了一个翻瓦片的益智游戏来娱乐奶牛。

    在一个M×N的骨架上,每一个格子里都有一个可以翻转的瓦片。瓦片的一面是黑色的,而另一面是白色的。对一个瓦片进行翻转,可以使黑变白,也可以使白变黑。然而,奶牛们的蹄子是如此的巨大而且笨拙,所以她们翻转一个瓦片的时候,与之有公共边的相邻瓦片也都被翻转了。

    那么,这些奶牛们最少需要多少次翻转,使所有的瓦片都变成白面向上呢?如果可以做到,输出字典序最小的结果(将结果当成字符串处理),如果不能做到输出"IMPOSSIBLE".

    【输入格式】

    第1行输入M和N;之后M行N列,输入游戏开始时的瓦片状态,0表示白面向上,1表示黑面向上。

    【输出格式】

    输出M行,每行N个用空格隔开的整数,表示对应的格子是否进行了翻动,0表示不翻动,1表示翻动。

    【输入样例】

    4 4

    1 0 0 1

    0 1 1 0

    0 1 1 0

    1 0 0 1

    【输出样例】

    0 0 0 0

    1 0 0 1

    1 0 0 1

    0 0 0 0

    【数据规模】

    对于50%的数据:1≤M,N≤5;

    对于70%的数据:1≤M,N≤10;

    对于100%的数据:1≤M,N≤15;

    看数据范围应该也猜得到是状态压缩+DFS。

    一开始直接枚举第一行的状态,即翻或不翻的状态(状压)。

    因为如果上一行是1,那么这一格一定要翻。

    N^2做一遍即可。

    理论复杂度O((2^M)*(N^2))

    code:

    #include <cstdio>
    using namespace std;
    char tc(){
        static char fl[1000000],*A=fl,*B=fl;
        return A==B&&(B=(A=fl)+fread(fl,1,1000000,stdin),A==B)?EOF:*A++;
    }
    int read(){
        char c;while(c=tc(),c<'0'||c>'9');int x=c-'0';
        while(c=tc(),c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0';
        return x;
    }
    int N,M,a[16][16],t[16][16],ans[16][16],w[16][16],res=2e9;
    void rotate(int x,int y){
        t[x][y]^=1;w[x][y]=1;
        if(x-1>=1)t[x-1][y]^=1;if(y-1>=1)t[x][y-1]^=1;
        if(x+1<=N)t[x+1][y]^=1;if(y+1<=M)t[x][y+1]^=1;
    }
    void check(int wks){
        int tk=0;
        for(int i=1;i<=N;i++)for(int j=1;j<=M;j++)w[i][j]=0,t[i][j]=a[i][j];
        for(int i=1;i<=M;i++)
            if(1<<i-1&wks){
                tk++;if(tk>=res)return ;//如果大于最优解直接return ;
                rotate(1,M-i+1);
            }//旋转第一行的(按wks状态旋转)
        for(int i=2;i<=N;i++)
            for(int j=1;j<=M;j++)
                if(t[i-1][j]){
                    tk++;if(tk>=res)return ;
                    rotate(i,j);
                }
        for(int j=1;j<=M;j++)if(t[N][j])return ;
        res=tk;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=M;j++)ans[i][j]=w[i][j];
    }
    void puts(){
        for(int i=1;i<=N;i++){
            for(int j=1;j<=M;j++)
                printf("%d ",ans[i][j]);
            puts("");
        }
    }
    int main(){
        freopen("fliptile.in","r",stdin);
        freopen("fliptile.out","w",stdout);
        N=read(),M=read();
            for(int i=1;i<=N;i++)
                for(int j=1;j<=M;j++)a[i][j]=read();
            for(int i=0;i<(1<<M);i++)
                check(i);
        if(res==2e9)puts("IMPOSSIBLE");
        else puts();
    }
  • 相关阅读:
    机器学习到深度学习资料
    安装CentOS 6停在selinux-policy-targeted卡住的问题解决
    U盘安装Ubuntu 16.04出现:Failed to load ldlinux.c32
    Ubuntu 16.04下使用UNetbootin制作的ISO镜像为U盘启动出现:Missing Operating System (mbr.bin)
    为什么Linux的Fdisk分区时First Sector为2048?
    Windows下将ISO镜像制作成U盘启动的工具(U盘启动工具/UltraISO/Rufus/Universal-USB)
    CentOS 6.9安装类型选择(Basic Server/Web Server)
    Java中String与byte[]的转换
    IntelliJ IDEA插件-翻译插件
    Mycat查询时出现:Error Code: 1064. can't find any valid datanode
  • 原文地址:https://www.cnblogs.com/Cptraser/p/7886880.html
Copyright © 2020-2023  润新知