解题思路:
这个题目刚开始看到的时候感觉无从下手,因为这个5*6的矩阵,我们不能将它的所有情况全部列举出来,一共有2的30次方的数据,过于庞大. 但是深入思考一下,其实没必要列举那麽多的数据,因为后面几行的数据2-5行都是根据第一行的矩阵的值算出来的. 假如这个结果矩阵叫做result[][]. 比如当result第一行的数据是1 0 0 0 0 0 的时候也就是说只按下第一个灯,这个时候第一行和第二行的灯的情况发生了变化.而这个时候我们要确定result的第二行的数据了.那麽该怎么确定第二行的值呢? 这样想, 当按照第二行的值进行灭灯的时候一定要将第一行的灯全部灭掉,因为只有这样才能确保第一行的灯是全部灭的,第二行以后的数据是对第一行的灯没有影响的.所以这个时候第一行的亮的所有列对应的第二行的result为1 只有这样才能保证第一行的灯全部被灭掉.就这样一行一行推到第5行. 当第5行的等全部灭掉的时候 第六行的result的值应该是全部为0的,而如果result第六行的值不是全部为零,说明就需要借助第六行的值将第五行的等灭掉,这样的result的值是错误的.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int arr[6][8];
int tmp[6][8];
int result[7][8];
int deal(int n) {
int k;
int i;
int row,col;
int value;
memcpy(tmp,arr,48*sizeof(int));
memset(result,0,56*sizeof(int));
for(k=0;k<6;k++) {
result[1][k+1]=n>>k&1;
}
for(row=1;row<6;row++) {
for(col=1;col<7;col++) {
if(result[row][col]) {
tmp[row][col]=1-tmp[row][col];
tmp[row-1][col]=1-tmp[row-1][col];
tmp[row+1][col]=1-tmp[row+1][col];
tmp[row][col-1]=1-tmp[row][col-1];
tmp[row][col+1]=1-tmp[row][col+1];
}
}
for(i=1;i<7;i++) {
if(tmp[row][i]) result[row+1][i]=1;
else result[row+1][i]=0;
}
}
value=0;
for(i=1;i<7;i++)
value+=result[6][i];
return !value;
}
int main() {
int n;
int i,j;
scanf("%d",&n);
while(n--) {
memset(arr,0,48*sizeof(int));
memset(result,0,56*sizeof(int));
for(i=1;i<6;i++)
scanf("%d %d %d %d %d %d",&arr[i][1],&arr[i][2],&arr[i][3],&arr[i][4],&arr[i][5],&arr[i][6]);
for(i=1;i<64;i++) {
if(i==9) continue;
if(deal(i)) break;
}
if(i==64) {
printf("there is no answer\n");
return 0;
}
for(i=1;i<=5;i++) {
for(j=1;j<=6;j++)
printf("%d ",result[i][j]);
printf("\n");
}
}
}
没有按照题目的标准格式输出,懒得修改程序了.哈哈! 感觉程序的代码质量不是很高,以后会慢慢提高的.很久没有写过代码了..希望我的代码质量能够逐渐恢复提高..