题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1010
方法:由于该题搜索的目标状态是准确的状态,即目标状态要求在到达的时候时间刚好是那么多,不能提前到达也不能延后到达,这和时间要在规定时间内或者求最小时间不一样,所以不用广搜用深搜。在深搜的时候要注意几个问题,
1.从一个顶点开始向四个方向深搜的之前(要是这个方向可以走的话),要把该顶点设置为不再可走(将该点设置为wall),这样来实现走过的路不能回去再走。而当该顶点四个方向深搜完成后,如果没有找到目标状态,则需要将其还原为可以走,因为有其他顶点开始的深搜会走到该点,而此时该点在这个状态下还没有走过。通过这种方式又实现了回溯。
2.当走到一个顶点发现该顶点就是door,但当前时间还不到规定时间,当然这种状态不是目标状态,但不会像其他点(road)那样,就此开始递归开启一段新的深搜,而是直接返回。
感想:体会下其中的剪枝。
代码:
View Code
#include<iostream> using namespace std; int maps[9][9]; int n,m,t; int doorX, doorY,startX, startY; char wall = 'X'; char door = 'D'; char start = 'S'; char emptyBlock = '.'; bool DFSSearch(int x, int y, int time) { if(x<1 ||x>n ||y <1||y>m) return false; int j = time-(abs(x-doorX)+abs(y-doorY)); if(j<0) return false; char temp = maps[x][y]; if(time==0 && maps[x][y] ==door) return true; else { if(maps[x][y]!=door) { maps[x][y] = wall; if(maps[x][y+1] != wall && DFSSearch(x,y+1,time-1)) return true; if(maps[x][y-1] != wall && DFSSearch(x,y-1,time-1)) return true; if(maps[x+1][y] != wall && DFSSearch(x+1,y,time-1)) return true; if(maps[x-1][y] != wall && DFSSearch(x-1,y,time-1)) return true; maps[x][y] = temp; return false; } return false; } } int main() { while(cin>>n>>m>>t) { if(n==0 && m==0 && t==0) break; else { char input; for(int i =1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>input; if(input == start) { startX = i; startY = j; } if(input == door) { doorX = i; doorY = j; } maps[i][j]=input; } int temp= t-(abs(startX-doorX)+abs(startY-doorY)); if(temp<0 ||temp%2==1) cout<<"NO"<<endl; else if(DFSSearch(startX,startY,t)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } return 0; }