关灯游戏增强版

本题的解题思路是:

(1) 首先对任意一初始状态,解是唯一的。

(2) 要使得第1行灯全部关闭,可以通过按下第2行相应的按钮来实现,因此依次按下2~5行的按钮,可以使得前面4行的灯全部关闭,但这时第5行可能还有些灯是开着的。所以这种方法行不通,原因是第1行的按钮没有按下。

(3) 第1行6盏灯,按下与否一共有2^6 = 64种可能。按下第1行后,为了使得第1行的灯全部关闭,第2行各按钮的按下与否就确定下来了;同样为了使得第2行的灯全部关闭,第3行各按钮的按下与否也就确定下来了;一直到第5行,其按法及各灯的状态也确定下来了。

(4) 枚举第1行6盏灯的64种按法,当某种按法使得第5行的灯全部关闭,则找到解了。因为矩阵为5×6的,规模很小,所以尽管需要枚举很多种情况,但也不会超时。

收获:

1.按位与运算符(&)

完整代码:

#include<stdio.h>
#include<string.h>
int light[5][6];
int ans[5][6];
void Anxia(int x,int y)//0表示关闭,1表示打开 
{
	ans[x][y] = 1;//按下的那一刻,要记录该位置的按下操作 
	light[x][y] = 1 - light[x][y];//当前位置取反
	if(x>0) light[x-1][y] = 1 - light[x-1][y];
	if(y>0) light[x][y-1] = 1 - light[x][y-1];
	if(x<4) light[x+1][y] = 1 - light[x+1][y];
	if(y<5) light[x][y+1] = 1 - light[x][y+1];	
} 

void process()
{
	int temp[5][6];
	int i,j;
	for(i=0;i<5;i++)
		for(j=0;j<6;j++)scanf("%d",&temp[i][j]);//总是忘记取地址符& 
	int z = 0;
	for(z=0;z<64;z++)//枚举第一行的64种可能 
	{
		memcpy(light,temp,sizeof(light));
		memset(ans,0,sizeof(ans));
		for(j=0;j<6;j++)//根据z求第1行各按钮是否按下
		{
			if(z&(1<<j))Anxia(0,j);
		}
		for(i=1;i<5;i++)
			for(j=0;j<6;j++)
				if(light[i-1][j] == 1)Anxia(i,j);
		for(j=0;j<6;j++)
		{
			if(light[4][j] == 1)break;
		}
		if(j>=6)
		{
			for(i=0;i<5;i++)
			{
				printf("%d",ans[i][0]);
				for(j=1;j<6;j++)printf(" %d",ans[i][j]);//输出结果是ans数组,不是light数组 
				printf("\n");
			}
			break;
		}	
	}
}

int main()
{
	int n = 0;
	int i = 0;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		printf("PUZZLE #%d\n", i);
		process();
	}
	return 0;
}	

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是用uniapp写一个关灯游戏的代码: <template> <view class="container"> <view class="title">关灯游戏</view> <view class="board"> <view class="row" v-for="(row, rowIndex) in board" :key="rowIndex"> <view class="cell" v-for="(cell, cellIndex) in row" :key="cellIndex" :class="{ on: cell }" @click="toggle(rowIndex, cellIndex)"></view> </view> </view> <view class="btn" @click="reset">重新开始</view> </view> </template> <script> export default { data() { return { board: [ [true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true] ] } }, methods: { toggle(row, col) { this.board[row][col] = !this.board[row][col] if (row > 0) this.board[row - 1][col] = !this.board[row - 1][col] if (row < 4) this.board[row + 1][col] = !this.board[row + 1][col] if (col > 0) this.board[row][col - 1] = !this.board[row][col - 1] if (col < 4) this.board[row][col + 1] = !this.board[row][col + 1] if (this.checkWin()) { setTimeout(() => { uni.showToast({ title: '你赢了!', icon: 'success' }) }, 500) } }, checkWin() { return this.board.every(row => row.every(cell => !cell)) }, reset() { this.board = [ [true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true] ] } } } </script> <style> .container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; } .title { font-size: 36px; font-weight: bold; margin-bottom: 20px; } .board { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 300px; height: 300px; background-color: #eee; border-radius: 10px; padding: 10px; } .row { display: flex; flex-direction: row; } .cell { width: 50px; height: 50px; background-color: #fff; border: 1px solid #ccc; margin: 5px; border-radius: 5px; } .cell.on { background-color: #333; } .btn { margin-top: 20px; padding: 10px 20px; background-color: #333; color: #fff; border-radius: 5px; cursor: pointer; } </style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值