翻格子游戏

前几天,朋友玩一个解谜类的游戏。中间有一个关卡,大概是这样的:

有一个5*5的板子,初始时,每个格子都是背面朝上。我们可以手动翻转任意一个格子,但其上下左右——如果有的话——的格子也会随之一起翻转,问怎么翻,可以将所有格子都翻到正面朝上。


当时蛮无聊,那就写段代码试试看吧。

这里,手动翻我们定义为主动,而被动当然就很清楚了。

不难想到,对任意一个格子来说,我们主动翻N次和N+2次的结果是一样的。因此,任何一种解决方案都是将每个格子主动翻0或1次。而且,翻格子的先后顺序也是无所谓的。于是,想到一种简单粗暴的办法,穷举呗,一共2^25种情形。

不多说,直接上代码。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int validate(int data, int index, int dimension)
{
	int ret;

	ret = (data >> index)&0x01;
	//left
	if(index%dimension > 0)
		ret ^= (data >> (index-1))&0x01;
	//right
	if(index%dimension < dimension-1)
		ret ^= (data >> (index+1))&0x01;
	//up
	if(index/dimension > 0)
		ret ^= (data >> (index-dimension))&0x01;
	//down
	if(index/dimension < dimension-1)
		ret ^= (data >> (index+dimension))&0x01;

	return ret;
}

int resolve(int data, int d)
{
	int ret = 0;
	int i;
	for (i=0; i<d*d; i++) {
		ret = validate(data, i, d);
		if (!ret)
			return 0;
	}
	return ret;
}

int main()
{
	int map=0;
	int ret = -1;
	int d = 5;

	for (map=0; map<pow(2,d*d); map++) {
		ret = resolve(map, d);
		if (ret) {
			printf("%x\n", map);
		}
	}
	return 0;
}

解决方案采用25个bit来描述,每个bit,1表示主动翻,0表示不主动翻。采用位操作不仅节省了空间,而且提高了效率。

结果发现,解决方案不止一种。


当然,需要注意的是,如果6*6的格子,用32bit整型会导致溢出。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值