0 1 1 0 1 0 0 0 0 0 0 0
1 0 0 1 1 1 0 1 0 0 0 0
0 0 1 0 0 1 --> 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0 0 0
0 0 1 0 1 0 0 0 0 0 0 0
0 1 1 1 1 1 0 1 1 0 0 0
0 1 1 0 0 1 --> 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 1 1 0 1 1 0 1 0
0 1 0 0 0 1 --> 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1 1 0 1 0
0 1 0 0 1 1 --> 0 0 0 1 0 0
1 0 0 1 0 1 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0
0 1 1 1 0 1 --> 0 0 0 1 0 0
1 0 0 0 0 1 0 1 0 0 0 0
0 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0
0 0 1 1 0 1 --> 0 0 0 1 0 0
0 1 1 0 0 1 0 1 1 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0
0 0 0 1 0 1 --> 0 0 0 1 0 0
0 0 0 1 0 1 0 1 1 1 0 0
0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0
0 0 0 0 0 1 --> 0 0 0 1 0 0
0 0 1 0 1 1 0 1 1 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0
0 0 0 0 0 0 --> 0 0 0 1 0 0
0 0 1 0 0 0 0 1 1 1 0 1
0 0 0 0 0 1 0 0 0 0 0 0从上面的模拟过程中可以看出来这样的方式还是有点问题存在,那么就是把所有的灯都压到了最后一行,那么最后一行应该怎么解决呢?????似乎有一些行不通
/////////////////////////////////////////////////////////////////////////////////////////
实在是没有什么思路所以看了一下题解,题解貌似都是什么高斯消元,听起来很高大上,不过不明白就是了,看了另外一个题解报告说是只要枚举第一行就行,只要第一行固定了那么下面的也就固定了,听起来是很有道理的,只要第一行是固定的那么下面的就按照上面的那种方式来就行了,直到找到一组解(http://www.hankcs.com/program/algorithm/poj-1222-extended-lights-out.html)。先按照这种理解方式做一下吧。
因为是枚举第一行,所以产生的状态也就是2^6,应该还是一个很小的数字。
测试数据确实没有问题,不过提交后无情的给了一个WA!!!
为啥呢????好吧,我也不知到为什么,不过可以测试一下数据
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WA 1
#include<stdio.h>
#include< string.h>
#include<iostream>
using namespace std;
#define maxn 10
// 2^6 = 64
int dir[ 5][ 2] = {{ 0, 0},{ 0, 1},{ 1, 0},{- 1, 0},{ 0,- 1}};
int c[ 10][ 10];
void changeXY( int b[][ 10], int x, int y); // 把xy坐标和四周的坐标改变
int OK( int x, int y); // 判断xy坐标是否合法
int Find( int b[][ 10]); // 第一行固定后,往下面查找,看看最后一行是否会变为全0
int main()
{
int T, t= 1;
scanf( " %d ", &T);
while(T--)
{
int i, j, k,a[ 10][ 10], b[ 10][ 10];
for(i= 1; i<= 5; i++)
for(j= 1; j<= 6; j++)
scanf( " %d ", &a[i][j]);
for(i= 1; i< 64; i++)
{
for(j= 1; j<= 5; j++)
for(k= 1; k<= 6; k++)
b[j][k] = a[j][k], c[j][k] = 0;
k = i;
for(j= 6; j> 0; j--)
{
if(k % 2)
{
changeXY(b, 1, j);
c[ 1][j] = 1;
}
k /= 2;
}
if(Find(b) == 1)
break;
}
printf( " PUZZLE #%d\n ", t++);
for(i= 1; i<= 5; i++)
for(j= 1; j<= 6; j++)
printf( " %d%c ", c[i][j], j == 6 ? ' \n ' : ' ');
}
return 0;
}
void changeXY( int b[][ 10], int x, int y) // 把xy坐标和四周的坐标改变
{
int i, nx, ny;
for(i= 0; i< 5; i++)
{
nx = x + dir[i][ 0];
ny = y + dir[i][ 1];
if(OK(nx, ny))b[nx][ny] = 1 - b[nx][ny];
}
}
int OK( int x, int y) // 判断xy坐标是否合法
{
if(x > 0 && x < 6 && y > 0 && y < 7)
return 1;
return 0;
}
int Find( int b[][ 10]) // 第一行固定后,往下面查找,看看最后一行是否会变为全0
{
int i, j;
for(i= 1; i<= 4; i++)
for(j= 1; j<= 6; j++)
{
if(b[i][j])
{
changeXY(b, i+ 1, j);
c[i+ 1][j] = 1;
}
}
for(i= 1; i<= 6; i++)
if(b[ 5][i]) return 0;
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////
找到BUG搜索应该从0开始的
////////////////////////////// /for(i=1; i <64; i++)
跟上一次做题的时候错的差不多,我晕,认栽了,仔细确实不能只嘴上说说的
//////////////////////////////////////////////////////////////////////////////////////////////// /
AC代码
#include<stdio.h>
#include< string.h>
#include<iostream>
using namespace std;
#define maxn 10
// 2^6 = 64
int dir[ 5][ 2] = {{ 0, 0},{ 0, 1},{ 1, 0},{- 1, 0},{ 0,- 1}};
int c[ 10][ 10];
void changeXY( int b[][ 10], int x, int y); // 把xy坐标和四周的坐标改变
int OK( int x, int y); // 判断xy坐标是否合法
int Find( int b[][ 10]); // 第一行固定后,往下面查找,看看最后一行是否会变为全0
int main()
{
int T, t= 1;
scanf( " %d ", &T);
while(T--)
{
int i, j, k,a[ 10][ 10], b[ 10][ 10];
for(i= 1; i<= 5; i++)
for(j= 1; j<= 6; j++)
scanf( " %d ", &a[i][j]);
for(i= 0; i< 64; i++)
{
for(j= 1; j<= 5; j++)
for(k= 1; k<= 6; k++)
b[j][k] = a[j][k], c[j][k] = 0;
k = i;
for(j= 6; j> 0; j--)
{
if(k % 2)
{
changeXY(b, 1, j);
c[ 1][j] = 1;
}
k /= 2;
}
if(Find(b) == 1)
break;
}
printf( " PUZZLE #%d\n ", t++);
for(i= 1; i<= 5; i++)
for(j= 1; j<= 6; j++)
printf( " %d%c ", c[i][j], j == 6 ? ' \n ' : ' ');
}
return 0;
}
void changeXY( int b[][ 10], int x, int y) // 把xy坐标和四周的坐标改变
{
int i, nx, ny;
for(i= 0; i< 5; i++)
{
nx = x + dir[i][ 0];
ny = y + dir[i][ 1];
if(OK(nx, ny))b[nx][ny] = 1 - b[nx][ny];
}
}
int OK( int x, int y) // 判断xy坐标是否合法
{
if(x > 0 && x < 6 && y > 0 && y < 7)
return 1;
return 0;
}
int Find( int b[][ 10]) // 第一行固定后,往下面查找,看看最后一行是否会变为全0
{
int i, j;
for(i= 1; i<= 4; i++)
for(j= 1; j<= 6; j++)
{
if(b[i][j])
{
changeXY(b, i+ 1, j);
c[i+ 1][j] = 1;
}
}
for(i= 1; i<= 6; i++)
if(b[ 5][i]) return 0;
return 1;
}