POJ2965-The Pilots Brothers' refrigerator

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

这道题目和POJ1753很相像,都是涉及到枚举算法。这题看起来很没头绪,但是仔细想想,枚举,可以针对目标手把一一处理,解题思路就出来了:


我们先假设只有一个+:
-  -  +  -
-  -  -  -
-  -  -  -
-  -  -  -
每个把手转换一次,则这个把手所在行和列上的所有把手都转换一次。重点是如果这个把手转动奇数次,无论多少,都和转一次一样;转动偶数次则等于没转!

把每个把手的坐标列出来:
0 1  2 3 4
1  -  -  +  -
2  -  -  -  -
3  -  -  -  -
4  -  -  -  -
要把所有把手都转换为开,那么目标把手必须转动奇数次,其余波及到的把手只能转动偶数次。

转动会波及到[1][3]把手的把手有[1][1],[1][2],[1][3],[1][4],[2][3],[3][3],[4][3]。转动完这七个把手发现,目标把手确实波及到了奇数次,也就是说它改变了初始状态,波及到的其余把手都转动了偶数次!也就是没有殃及无辜,没有改变它们的状态。所以要改变目标把手的状态,只要把波及到它的七个把手通通进行转动操作就行了。

然后再回到题目,需要转动的把手不止一个,当出现如样例输入的情况时:
0 1  2 3 4
1  -  + -  -
2  -  -  -  -
3  -  -  -  -
4  -  + -  -
需要转动的把手分别为
行 1 1 1 1 2 3 4

列 1 2 3 4 2 2 2

行 1 2 3 4 4 4 4

列 2 2 2 1 2 3 4

进行完这么多次操作后所有把手确实都打开了,但是题目的要求是要输出次数最小的转动过程,所以去掉重复偶数次的操作后一共6次,分别为:

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

DONE!

贴出一次AC的代码:

#include <stdio.h>
#include <string.h>
int state[6][6];
int main()
{
	char ch;
	int i, j, r, count = 0;
	memset(state, 0, sizeof(state));
	for (i = 1; i<=4; ++i)
	{
		for (j = 1; j<=4; ++j)
		{
			scanf("%c", &ch);
			if(ch == '+')
			{
				for(r=1; r<=4; ++r)	state[i][r]++;
				for(r=1; r<=4; ++r)	state[r][j]++;
				state[i][j]--;
			}
		}
		getchar();
	}	
	for (i = 1; i<=4; ++i)
		for (j = 1; j<=4; ++j)
			if(state[i][j]%2 == 1)
				count++;
	printf("%d\n", count);
	for (i = 1; i<=4; ++i)
		for (j = 1; j<=4; ++j)
			if(state[i][j]%2 == 1)
				printf("%d %d\n", i, j);
	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值