POJ 2965

4x4冰箱门谜题

题目连接:点击打开链接

题目大意:

这一题大意如下:

      一个冰箱上有4*4共16个开关,改变任意一个开关的状态(即开变成关,关变成开)时,此开关的同一行、同一列所有的开关都会自动改变状态。要想打开冰箱,要所有开关全部打开才行。

     输入:一个4×4的矩阵,+表示关闭,-表示打开;

   输出:使冰箱打开所需要执行的最少操作次数,以及所操作的开关坐标。

#include<iostream>
#include<stdio.h>
using namespace std;
bool vis[10][10] = { false };                                          //将棋盘初始状态全部设置为false
int ri[16], cj[16]; 
int step;                                                              //记录改变状态的次数
bool flag;
bool finish()                                                           //开关为全开的状态
{
	for(int i=3;i<7;i++)
		for (int j = 3; j < 7; j++)
		{
			if (vis[i][j] != true)
				return false;
		}
	return true;
}
void filp(int row,int  col)                                          //翻棋,也就是改变开关状态
{
	vis[row][col] = !vis[row][col];
	for (int i = 3; i < 7; i++)                                  //注意翻棋方法,防止超时
	{                                                            // 这里使用10x10矩形,多余操作有“三圈”翻棋
		vis[i][col] = !vis[i][col];
	}
	for (int j = 3; j < 7; j++)
	{
		vis[row][j] = !vis[row][j];
	}
}
void  dfs(int row, int col, int deep)     
{
	if (deep == step)                                            //判断是否为全为开
	{
		flag = finish();
		return;
	}
	if (flag || row == 7) return;                                //判断是否超界
	filp(row, col);                                               //翻棋
	ri[deep] = row;                                               //记录被翻棋的横坐标
	cj[deep] = col;                                               //记录被翻棋的纵坐标
	if (col < 6)                           
		dfs(row, col+1, deep + 1);
	else
		dfs(row+1,3,deep+1);              
	filp(row, col);
	if (col < 6)
		dfs(row, col + 1, deep);          
	else
		dfs(row+1,3,deep);
	return ;
}
int main()
{
	int i, j;
	char temp;
	for (i = 3; i <= 6; i++)                                        //这里使用10x10矩形,多余操作有“三圈”翻棋!  
	{
		for (j = 3; j <= 6; j++)
		{
			cin >> temp;
			if (temp == '-')
				vis[i][j] = true;
		}
	}
	
	for (step = 0; step <= 16; step++)                             //考虑到4x4=16格,而每一格只有黑白两种情况,则全部的可能性为2^16  
	{
		dfs(3, 3, 0);
		if (flag)                             
			break;
	}
	
	cout << step << endl;
	for ( i = 0; i < step; i++)
	{
		cout << ri[i] - 2 << " " << cj[i] - 2 << endl;           //因为横纵坐标是从3开始的,所以要减去2
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值