poj1222 EXTENDED LIGHTS OUT 开关问题

来源:互联网 发布:时尚杂志软件 编辑:程序博客网 时间:2024/06/01 07:33

和poj3279 一样

题意:有一个5*6的格子,每个格子有两种颜色,每个格子可以翻转,每翻转一个格子它以及其上下左右四个格子都会变为它相反的状态,问最少反转哪些格子可以把这些格子都变成相同的状态,解有多个时,输出字典序最小的一个

经典的开关问题,只要第一行的状态确定其他行的状态也将确定,故暴力枚举第一行的开关情况,判断最后一行的状态是否符合题意

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int dx[5]={-1,0,0,0,1};const int dy[5]={0,-1,0,1,0};int M,N,tile[16][16],opt[16][16],flip[16][16];int get(int x,int y){int c=tile[x][y];for(int d=0;d<5;d++){    int x2=x+dx[d],y2=y+dy[d];    if(0<=x2&&x2<M&&0<=y2&&y2<N)        c+=flip[x2][y2];}return c%2;}int calc(){for(int i=1;i<M;i++)    for(int j=0;j<N;j++)    if(get(i-1,j)!=0)      flip[i][j]=1;for(int j=0;j<N;j++)    if(get(M-1,j)!=0)        return -1;int res=0;for(int i=0;i<M;i++)    for(int j=0;j<N;j++)    res+=flip[i][j];return res;}int main(){int res=-1;int x;cin>>x;M=5;N=6;for(int c=1;c<=x;c++){for(int i=0;i<M;i++)    for(int j=0;j<N;j++)        cin>>tile[i][j];for(int i=0;i<1<<N;i++){    memset(flip,0,sizeof(flip));    for(int j=0;j<N;j++)        flip[0][N-j-1]=i>>j&1;    int num=calc();    if(num>=0){        res=num;        memcpy(opt,flip,sizeof(flip));    }}cout<<"PUZZLE #"<<c<<endl;if(res<0)    printf("IMPOSSIBLE\n");else for(int i=0;i<M;i++)         for(int j=0;j<N;j++)            printf("%d%c",opt[i][j],j+1==N? '\n':' ');}}



1 0