poj 1222 反转问题 枚举(0ms 过)

来源:互联网 发布:java接口安全 编辑:程序博客网 时间:2024/06/06 02:43

看网上的解答,说什么高斯消元法。。。我现在还没看到那,反正这是挑战书上的缩减版原题

我们可以先枚举第一行所有的翻转情况,才64种。

之后第一行已经确定了,然后看第2行,如果第一行某个位置为1,那么在同一列的第2行这个位置必须反转。。

(因为第一行已经确定,不能再反转了,而影响第一行的,也只有在同一列的第2行),这样我们可以确定了

前N-1行,全部为0,最后单独检查最后一行,是否全部为0

#include<stdio.h>int dx[5]={-1,0,0,0,1};int dy[5]={0,-1,0,1,0};int d[5][6];int mid[5][6];int get(int x,int y)//看看这个格子是否应该反转{int c=d[x][y];int i,x2,y2;for(i=0;i<5;i++){x2=x+dx[i];y2=y+dy[i];if(0<=x2&&x2<5&&0<=y2&&y2<6)c+=mid[x2][y2];}return c%2;}int cal(){int i,j;   for(i=1;i<5;i++)   for(j=0;j<6;j++)   {   if(get(i-1,j)!=0)   mid[i][j]=1;   }for(j=0;j<6;j++)if(get(4,j)!=0)return 0;return 1;}int main(void){int i,j,k,T,v,num=1;;scanf("%d",&T);while(T--){memset(d,0,sizeof(d));for(i=0;i<5;i++)for(j=0;j<6;j++)scanf("%d",&d[i][j]);    for(i=0;i<1<<6;i++){memset(mid,0,sizeof(mid));for(j=0;j<6;j++){mid[0][5-j]=i>>j&1;}if(cal()){printf("PUZZLE #%d\n",num);num++;for(k=0;k<5;k++){for(v=0;v<6;v++)printf("%d ",mid[k][v]);printf("\n");}break;}}}}


 

 

0 0
原创粉丝点击