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!!!
为啥呢????好吧,我也不知到为什么,不过可以测试一下数据
找到BUG搜索应该从0开始的///////////////////////////////for(i=1; i<64; i++)
跟上一次做题的时候错的差不多,我晕,认栽了,仔细确实不能只嘴上说说的
#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;
}