题目阐述:
有一个由按钮组成的矩阵,5行6列,每按一次改变原来颜色;具体事例如下图所示:
请写一个程序,判断需要按哪些按钮,能够是灯泡全部熄灭。(相关问题细节不再重复)
刚刚
输入:
2
0 1 1 0 1 0
1 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 0 1 1
1 0 1 1 0 0
0 1 0 1 0 0
输出:
PUZZLE #1
1 0 1 0 0 1
1 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0
PUZZLE #2
1 0 0 1 1 1
1 1 0 0 0 0
0 0 0 1 0 0
1 1 0 1 0 1
1 0 1 1 0 1
贴上源代码:
#include "stdio.h"
int puzzle[6][8],press[6][8];
bool guess()
{
int c,r;//r - row;
//c - column
for (r=1;r<5;c++){
for (c=1;c<=6;c++){
press[r+1][c]=(press[r][c]+press[r][c-1]+press[r][c-1]+press[r][c+1]+puzzle[r][c])%2;
}
}
for (c=1;c<=6;c++){
if ((press[5][c-1]+press[5][c]+press[5][c+1]+press[4][c])%2!=puzzle[5][c]){
return false;
}
}
return true;
}
void enummerate()
{
int c;
bool success;
for (c=1;c<=7;c++){
press[1][c]=0;
}
while (guess()==false){
press[1][1]++;
c=1;
while (press[1][c]>1){
press[1][c]=0;
c++;
press[1][c]++;
}
}
}
int main()
{
int cases,i,r,c;
scanf("%d",&cases);
for (r=0;r<6;r++){
press[r][0]=0;
press[r][7]=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<=6;c++){
scanf("%d",&puzzle[r][c]);
}
}
enummerate();
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;
}
附上自己理解:
实际上本篇程序的意思是:我先模拟出2^6中情形(为什么是这么多呢?因为左右,前后都会对此次按键产生影响),也就是第一行的所有情况,再在这样一个大循环里面去不断的试验,比如每一种情况中,必须要判断能够使最后一行恰好熄灭。
实际上,本程序简洁之处在于,使用一种巧妙的方法去设计那64中情形,即递加,模拟出一个二进制情况而已。
本题目是POJ原题。