在学北大郭玮和刘家瑛老师的算法基础,做点笔记
press[i+1][j] = (puzzle[i][j] + press[i][j] + press[i][j-1] + press[i][j+1] + press[i-1][j]) % 2;
if( puzzle[5][i] != (press[5][i] + press[4][i] + press[5][i-1] + press[5][i+1] ) %2);
0 0 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
0 0 1 0 0 0
……
1 1 1 1 1 1
#include
int puzzle[6][8], press[6][8]; //puzzle为灯的状态矩阵,0表示熄灭,1表示亮;press为按钮状态矩阵,0表示没按下,1表示按下
typedef int bool;
bool guess()
{
int c, r;
//先根据第一行的状态依次推算出其余部分状态
for (c = 1; c < 5; c++)
{
for (r = 1; r < 7; r++)
{
press[c + 1][r] = (puzzle[c][r] + press[c][r - 1] + press[c][r + 1] + press[c][r] + press[c - 1][r]) % 2;
}
}
//判断第五行是否全部熄灭,从而判断该方案是否符合条件
for (c = 1; c < 7; c++)
{
if (puzzle[5][c] != (press[5][c] + press[4][c] + press[5][c - 1] + press[5][c + 1]) % 2)
return 0;
}
return 1;
}
void enumerate()
{
int c;
//将要第一行初始化为0 0 0 0 0 0
for (c = 1; c < 7; c++)
{
press[1][c] = 0;
}
//如果当前枚举的按钮状态不能使灯全熄灭,则继续枚举新的情况
while (guess() == 0)
{
press[1][1]++;
c = 1;
while (press[1][c] > 1) //判断当前位是否大于1,大于1则进位,且继续判断下一位,直到不需进位
{
press[1][c] = 0;
c++;
press[1][c]++;
}
}
return;
}
int main()
{
int cases, i, r, c;
scanf("%d", &cases);
//将第0列及第7列的元素置0,这两列不能代表实际的按钮状态
for (r = 0; r < 6; r++)
{
press[r][0] = press[r][7] = 0;
}
//将第0行的press状态置0,这一行不能代表实际的按钮状态
for (c = 1; c < 7; c++)
{
press[0][c] = 0;
}
for (i = 0; i < cases; i++)
{
for (r = 1; r < 6; r++)
{
for (c = 1; c < 7; c++)
{
scanf("%d", &puzzle[r][c]);
}
}
//为当前case寻找解决方案
enumerate();
printf("puzzle#%d\n", i + 1);
for (r = 1; r < 6; r++)
{
for (c = 1; c < 7; c++)
{
printf("%d ", press[r][c]);
}
printf("\n");
}
}
return 0;
}