枚举--熄灯问题

题目阐述:

有一个由按钮组成的矩阵,5行6列,每按一次改变原来颜色;具体事例如下图所示:

POJ <wbr>2811:熄灯问题


POJ <wbr>2811:熄灯问题

请写一个程序,判断需要按哪些按钮,能够是灯泡全部熄灭。(相关问题细节不再重复)

刚刚

输入:

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原题。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值