poj2965 The Pilots Brothers' refrigerator(枚举)

#include<iostream>
#include<vector>
#include<string>
#include<queue>
/**
*	哇偶。。。。。一遍过。。。。真是太不习惯了
*	本题相当于poj1753的进阶版,可以先完成poj1753,再来尝试这题
*/
/**
* @note 题意:
	  有一冰箱,上面4x4共16个开关("-"状态表示open,"+"状态表close),  
      当改变一个开关状态时,该开关所在行、列的全部开关状态也会同时改变。  
      给出一个开关状态,问从该状态开始,使得所有开关打开(全"-"), 
      至少需要操作多少步,并把操作过程打印出来(打印所操作开关的行列坐标,坐标从1开始)
 思路:主要是理解操作之间的不相关性,即操作间顺序的不相关(操作(1,1)->操作(2,2)等效于操作(2,2)->操作(1,1)),
		和操作次数的不相关(对同一个开关操作0次等效于操作2次)

*/
using namespace std;
int state[][4] = { { 8,4,2,1 },{ 15,15,15,15 } };


///field数组储存开关信息用int中的前四位来表示开关的一行,1表示打开,op储存操作信息
struct my_data
{
	int field[6];
	bool op[5][5];
};
///读取数据 
void read(int field[6])
{
	for (int i = 1; i <= 4; i++) 
	{
		for (int j = 1; j <= 4; j++) 
		{
			field[i] <<= 1;
			char temp;
			cin >> temp;
			if (temp=='-')
			{
				field[i] |= 1;
			}
		}
	}
}

///依题意规则翻转开关
void flip(int i, int j,my_data &data) 
{
	--j;
	for (size_t temp = 1; temp <=4 ; temp++)
	{
		if (temp!=i)
		{
			data.field[temp] ^= state[0][j];
		}
	}
	data.field[i] ^= state[1][j];
}

/**
* @param n:还可以最多翻转开关的数量  
* i:正在检测开关的行数  j:列数  data:储存开关信息的结构体
* @return 当全部开关都打开时返回true
*/
bool find_result(int n,int i,int j,my_data &data)
{
	if (n == 0)
	{
		///判断是否开关是否都打开
		return data.field[1] == 15
			&& data.field[1] == data.field[2]
			&& data.field[2] == data.field[3]
			&& data.field[3] == data.field[4];
	}
	j++;
	if (j > 4)
	{
		i += 1, j = 1;
	}
	if (i > 4)
	{
		return false;
	}

	for (; i <= 4; i++)
	{
		for (; j <= 4; j++)
		{
			flip(i, j, data);
			data.op[i][j] = true;
			if (find_result(n - 1, i, j,data))
			{
				return true;
			}
			data.op[i][j] = false;
			flip(i, j, data);
		}
		j = 1;
	}
	return false;
}

void get_result(my_data &data)
{

	for (size_t i = 0; i <= 16; i++)
	{
		if (find_result(i,1,0,data))
		{
			cout << i << endl;
			///遍历输出所有操作
			for (size_t i2 = 1; i2 <= 4; i2++)
			{
				for (size_t i3 = 0; i3 <=4; i3++)
				{
					if (data.op[i2][i3])
					{
						cout << i2 << " " << i3 << endl;
					}
				}
			}
			return;
		}
	}
	cout << "Impossible" << endl;
}


int main() 
{
	struct my_data data_temp;
	memset(data_temp.field, 0, sizeof(data_temp.field));
	memset(data_temp.op, false, sizeof(data_temp.op));
	read(data_temp.field);
	get_result(data_temp);
	system("pause");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值