和之前做过的一道搜索题 POJ-1753-Filp Game-基本相似。
本题需要记录到达门全部打开状态前 有哪些门打开过,也就是说要记忆路径,以免重复计算。
也叫记忆化搜索,刚接触这类题目,蛮有意思的。
传送门:POJ-2965-The Pilots Brothers’ refrigerator
#include <stdio.h>
#define INF 0xFFFFFF
struct step {
int x;
int y;
}step[20],_step[20];
int map[4][4];
int minSteps = INF;
int checkMap(){
int i,j;
for(i=0; i<4; i++){
for(j=0; j<4; j++){
if(map[i][j]){
return false;
}
}
}
return true;
}
int printMap(){
int i,j;
printf("\n");
for(i=0; i<4; i++){
for(j=0; j<4; j++){
map[i][j] == 0?(printf("-")):(printf("+"));
}
printf("\n");
}
printf("\n");
return true;
}
void converseMap(int x, int y){
int i;
for(i=0; i<4; i++)
map[x][i] = !map[x][i];
for(i=0; i<4; i++)
map[i][y] = !map[i][y];
map[x][y] = !map[x][y];
}
void dfs(int x, int y, int steps){
int i,j,k;
if(x == 4){
if(checkMap()){
if(steps < minSteps) {
minSteps = steps;
for(k=0; k<minSteps; k++) {
_step[k].x = step[k].x;
_step[k].y = step[k].y;
}
// for(i=0; i<steps; i++)
// printf("*%d %d*\n",_step[i].x+1,_step[i].y+1);
// printMap();
}
}
return;
}
converseMap(x, y);
step[steps].x = x;
step[steps].y = y;
if(y == 3){
dfs(x+1, 0, steps+1);
converseMap(x, y);
dfs(x+1, 0, steps);
}else{
dfs(x, y+1, steps+1);
converseMap(x, y);
dfs(x, y+1, steps);
}
}
int main(){
int i,j;
char _map[5];
// freopen("data.in", "r", stdin);
minSteps = INF;
for(i=0; i<4; i++){
if(scanf("%s", _map) == EOF) return 0;
for(j=0; _map[j]; j++){
map[i][j] = _map[j] == '-' ? 0: 1;
}
}
dfs(0, 0, 0);
printf("%d\n",minSteps);
for(i=0; i<minSteps; i++)
printf("%d %d\n",_step[i].x+1,_step[i].y+1);
return 0;
}