导航

poj 2965 The Pilots Brothers' refrigerator

Posted on 2013-08-18 12:16  勇敢的炮灰  阅读(142)  评论(0)    收藏  举报

点击打开链接

The Pilots Brothers' refrigerator
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 15703   Accepted: 5928   Special Judge

Description

The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.

There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.

The task is to determine the minimum number of handle switching necessary to open the refrigerator.

Input

The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.

Output

The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.

Sample Input

-+--
----
----
-+--

Sample Output

6
1 1
1 3
1 4
4 1
4 3
4 4

题目大意是在一个4 *4的棋盘上,你可以对任意一个点做操作,操作的方法是把这个点所在的行和列都求反(+变为-, -变为+)求把整图变为全部是-的最少歩数和每一步的选择的点

这题用迭代加深的深搜做效果比较好,可惜当时我没想起来,从小到大枚举最小歩数,然后以最小歩数为上界开始深搜,搜到就输出结果。我用的是广搜,本来广搜是很不适合记录路径的,题目要求输出路径,所以我就费了一点事,另开了一个数组father来记录每个节点的上一个节点,这样搜到以后顺着这个father就能找回去了,但是效率非常非常非常慢,以至于900+MS擦边过的,侥幸吧,c++交会超时,g++交能过,贴上我的BFS的代码吧,dfs的网上有很多了

#include<stdio.h>
#include<queue>
using namespace std;
int step[0x10000];
bool flag[0x10000];
int father[0x10000][2];
int row[4][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}};
int line[4][4] = {{0, 4, 8, 12}, {1, 5, 9, 13}, {2, 6, 10, 14}, {3, 7, 11, 15}};
queue<int> q;
int calculate(int num, int i)
{
	int p = 0;
	int j;
	for(j = 0; j < 4; j++)
	{
		p |= 1 << row[i % 4][j];
		p |= 1 << line[i / 4][j];
	}
	return  p ^ num;
}
int bfs()
{
	int num, new_num;
	int i;
	while(!q.empty())
	{
		num = q.front();
		q.pop();
		for(i = 0; i < 16; i++)
		{
			new_num = calculate(num, i);
			if(flag[new_num] == 1)
				continue;
			father[new_num][0] = i;
			father[new_num][1] = num;
			if(new_num == 0)
			{
				return step[num] + 1;
			}
			flag[new_num] = 1;
			step[new_num] = step[num] + 1;
			q.push(new_num);
		}
	}
	return -1;
}
int main()
{
	int i = 16;
	char ch;
	int num = 0;
	while(i--)
	{
		scanf("%c", &ch);
		if(ch == ' ' || ch == '\n')
		{
			i++;
			continue;
		}
		num <<= 1;
		if(ch == '+')
			num++;
	}
	flag[num] = 1;
	step[num] = 0;
//	father[num][0] = 0;
	q.push(num);
	int t = bfs();
	printf("%d\n", t);
//	int array[101];
	int temp = 0;
	for(i = 0; i < t; i++)
	{
		printf("%d %d\n", 4 - father[temp][0]% 4, 4 - father[temp][0]/ 4);
		temp = father[temp][1];
	}
	return 0;
}