The Pilots Brothers' refrigerator
Time Limit: 1000MS | | Memory Limit: 65536K | ||
Total Submissions: 11826 | | Accepted: 4373 | | 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 rowi 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
|
此提一共有三种解法:
1.枚举
最朴素的算法,但是一开始我居然不知道如何来枚举。大概的原理是:以位置1,1开始变化。得到16种位置的最小解法,然后选最少的一个就OK。
2.BFS
一开始,我想到的就是这个解法。原来还认为是枚举,但是仔细看看应该是BFS。因为是记录给自己看的,所以解法不说。
3.直接给结果
这题和之前的黑白子差不多。不过那题我是BFS过的。所以这题,想看看枚举人家怎么做的。但是没想到搜索到了这种解法,对比了一下discuss和他的讲解。下面将代码贴出来。
10#include <stdio.h>
11
12#define Len 4
13
14void main()
15{
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61}
转载请注明出处:優YoU
提示:这题和POJ1753翻转棋的思想是一致的,需要注意的是要求输出翻转过程,因此不能用BFS,必须用DFS(找到目标后,还要过程回溯)
与POJ1753相比,这题还要注意翻棋的方法,若不注意会大大浪费时间导致超时,因为是整行整列翻转,在边界处会出现很多多余操作。代码中详细说明
同样本题有两种方法,Enum和Bit ,下面分别贴出这两种代码
//Memory Time
//240K
//本题由于要输出每次翻转的棋子,因此不适宜用BFS,应该使用DFS输出完整路径
#include<iostream>
usingnamespacestd;
boollock[10][10]={false};
boolflag;
intstep;
intri[16],cj[16];
boolisopen(void)
{
for(inti=3;i<7;i++)
for(intj=3;j<7;j++)
if(lock[i][j]!=true)
returnfalse;
returntrue;
}
voidflip(introw,intcol)
{
lock[row][col]=!lock[row][col];
for(inti=3;i<=6;i++)
lock[i][col]=!lock[i][col];
for(intj=3;j<=6;j++)
lock[row][j]=!lock[row][j];
return;
}
voiddfs(introw,intcol,intdeep)
{
if(deep==step)
flag=isopen();
return;
if(flag||row==7)return;
flip(row,col);
ri[deep]=row;
cj[deep]=col;
dfs(row,col+1,deep+1);
flip(row,col);
dfs(row,col+1,deep);
return;
}
intmain(void)
{
chartemp;
inti,j;
for(i=3;i<7;i++)
for(j=3;j<7;j++)
cin>>temp;
if(temp=='-')
lock[i][j]=true;
for(step=0;step<=16;step++)
dfs(3,3,0);
if(flag)break;
cout<<step<<endl;
for(i=0;i<step;i++)
cout<<ri[i]-2<<' '<<cj[i]-2<<endl;
return0;
}
消除行号
=============华丽的分割线=============
10
11int chess;
12int step;
13bool flag=false;
14intri[16],cj[16];
15
16boolisopen(void)
17{
18if(chess==0xFFFF)
19returntrue;
20else
21returnfalse;
22}
23
24void flip(int bit)
25{
26
27int row=bit/4;
28int col=bit%4;
29for(intc=0;c<4;c++)
30
31for(intr=0;r<4;r++)
32
33return;
34}
35
36voiddfs(intbit,intdeep)
37{
38if(deep==step)
39
40
41return;
42
43
44if(flag||bit>15)return;
45
46int row=ri[deep]=bit/4;
47int col=cj[deep]=bit%4;
48
49
50
51dfs(bit+1,deep+1);
52
53
54
55
56
57dfs(bit+1,deep);
58
59
60return;
61}
62
63int main(void)
64{
65
66
67char temp;
68inti,j;
69for(i=0;i<4;i++)
70for(j=0;j<4;j++)
71
72cin>>temp;
73if(temp=='-')
74
75
76
77
78
79for(step=0;step<=16;step++)
80
81dfs(0,0);
82if(flag)
83break;
84
85
86cout<<step<<endl;
87for(i=0;i<step;i++)
88cout<<ri[i]+1<<' '<<cj[i]+1<<endl;
89return0;
90}