poj2965:The Pilots Brothers' refrigerator
Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 10158
Accepted: 3707
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
Source
Northeastern Europe 2004, Western Subregion
题目大意:一个冰箱有16个开关,呈方形分布(4*4矩阵),“+”表示关闭,“-”表示开着,当所有的开关为“+”时冰箱才能打开。当去翻转一个开关时,在该开关所在列和行的所有开关都要翻转,即开变关,关变开。问至少需要多少次才能打开冰箱。
网上看到的一种用DFS方法的代码:
#include<iostream>
using namespace std;
bool board[16];
int is[16];
int js[16];
bool check(){
for(int i=0;i<16;i++){
if(board[i]!=1)
return false;
}
return true;
}
void init(){
char a;
for(int i=0;i<16;i++){
cin>>a;
if(a=='+'){
board[i]=0;
}else{
board[i]=1;
}
}
}
void flip(int pos){
int i=pos/4;
int j=pos%4;
board[pos]=!board[pos];
for(int m=0;m<4;m++){
board[i*4+m]=!board[i*4+m];
board[(m)*4+j]=!board[(m)*4+j];
}
}
bool dfs(int pos,int step){
if(check()){
cout<<step<<endl;
for(int i=0;i<step;i++){
cout<<is[i]<<" "<<js[i]<<endl;
}
return true;
}
if(pos>=16){
return false;
}
if(dfs(pos+1,step))//这里是什么意思?为什么这里递归step不要加1
return true;
flip(pos);
is[step]=pos/4+1;//这里记录下了什么?
js[step]=pos%4+1;
if(dfs(pos+1,step+1))
return true;
flip(pos);
return false;
}
int main(){
init();
dfs(0,0);
}
小白看了很长时间不懂,我想请教一下这里dfs函数是什么意思?不能理解是如何搜索的。
一般DFS接受一个图的节点(状态),然后搜索完一个分支回溯再搜索另一个分支,直到搜索完整个图。
对于这个题目来说节点是什么?分支又是什么呢?而且每个节点是通过什么方式表示是否被访问过了呢?