POJ 1222 EXTENDED LIGHTS OUT

来源:互联网 发布:联发科x10优化 编辑:程序博客网 时间:2024/05/16 17:40

1.题目描述:点击打开链接

2.解题思路:本题是经典的反转开关问题,可以用集合来枚举。我们可以事先指定好第一行的反转方式,然后根据第一行的情况,推算出第2行,第3行一直到第5行的反转方式,最后只需要判断一下第5行是否均为0即可。那么如何判断第(i,j)处是否需要反转呢,可以考察(i-1,j)这个格子,如果它仍然是1,那么就必须反转(i,j),判断的方法很简单,因为反转的效果可以叠加,因此只需要看该处格子的颜色叠加上反转效果后的颜色是多少即可。

3.代码:

#include<iostream>#include<algorithm>#include<cassert>#include<string>#include<sstream>#include<set>#include<bitset>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<cctype>#include<list>#include<complex>#include<functional>using namespace std;#define me(s)  memset(s,0,sizeof(s))#define rep(i,n) for(int i=0;i<(n);i++)#define pb push_backtypedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair <int,int> P;const int N=10;int puzzle[N][N];int flip[N][N];int dx[]={-1,1,0,0,0};int dy[]={0,0,-1,1,0};bool inside(int x,int y){return x>=0&&x<5&&y>=0&&y<6;}int get(int x,int y) //判断(x,y)处格子的颜色{    int c=puzzle[x][y];    for(int i=0;i<5;i++)    {        int nx=x+dx[i],ny=y+dy[i];        if(inside(nx,ny))            c+=flip[nx][ny];    }    return c%2;}bool test(){    for(int i=1;i<5;i++)        for(int j=0;j<6;j++)        if(get(i-1,j))        flip[i][j]=1;    for(int i=0;i<6;i++)//如果最后一行仍然有1,那么return false        if(get(4,i))return false;    return true;}int main(){    int T;    scanf("%d",&T);    for(int kase=1;kase<=T;kase++)    {        rep(i,5)rep(j,6)scanf("%d",&puzzle[i][j]);        int ALL=1<<6;        printf("PUZZLE #%d\n",kase);        for(int i=0;i<ALL;i++)        {            me(flip);            for(int j=0;j<6;j++)                flip[0][5-j]=i>>j&1;            if(test())            {                for(int i=0;i<5;i++)                    for(int j=0;j<6;j++)                    printf("%d%c",flip[i][j]," \n"[j==5]);                break;            }        }    }}


0 0
原创粉丝点击