POJ2965 解题报告

                                      The Pilots Brothers' refrigerator

                                      Time Limit: 1000MS
                                      Memory Limit: 65536K   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

分析:
     从数据上看,第一想到的是用搜索,加上位运算优化还比较好写,由于是当做比赛马上就开始码了
    到快码完,才发现的有个更加简单的方法而且更快O(n2)的算法.
由于目标是要将所有的+变成-,
注意到:
如果对 一个十字形的格点集合都做一次如题操作的话,只有十字中心的格点做了奇数次变化,其他的所有格点都做了偶数次,也就是状态不变

于是很容易给出代码,由于是写完搜索后才想到的所以只有搜索的代码

推荐上面的做法,就不给注释了
#include <iostream>
#include <queue>
#define Close 65535
using namespace std;
struct node {
	int x, y, k, pr;
};
queue<int> g;
node f[Close + 1];
int pos[] = {1, 4, 3, 2}, n = 0, flag = 1;
int dir[] = {0, 4383, 8751, 17487, 34959, 4593, 8946, 17652, 35064, 7953, 12066,
			 20292, 36744, 61713, 61986, 62532, 63624
			};
void bfs (int x) {
	g.pop();
	if (x == 0) {flag = 0; return;}
	for (int i = 1, m = 0; i <= 16; i++) {
		m = x ^ dir[i];
		if (!f[m].k && m != n) {
			node k;
			k.x = 4 - (i - 1) / 4 , k.y = pos[i % 4], k.k = f[x].k + 1, k.pr = x;
			f[m] = k, g.push (m);
		}
	}
}
int main() {
	char ch;
	for (int i = 1; i <= 16; i++) {
		cin >> ch;
		n <<= 1;
		if (ch == '+') n++;
	}
	g.push (n);
	while (!g.empty() && flag ) bfs (g.front() );
	cout << f[0].k << endl;
	for (int i = 0; f[i].k != 0; i = f[i].pr)
		cout << f[i].x << ' ' << f[i].y << endl;
	return 0;
}

http://www.cnblogs.com/keam37/ keam所有 转载请注明出处

posted @ 2014-05-23 23:40  keambar  阅读(218)  评论(0)    收藏  举报