Tempter of the Bone
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1010
解题思路:
大一时,学长讲这题时,是用dfs讲的,当时并没在意学长为什么用dfs讲,如今身为学长,给他们将这题时,想换一种方法用bfs敲出来,/结果wrong到哭,然后再仔细读题才发现只有到T时刻才开门,你可以在中途到处转,直到到了那时刻到终点就行了。。。
AC代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n,m,T;
int dx[] = {-1,0,1,0}, dy[] = {0,-1,0,1};
char maze[10][10];
int start_x,start_y;
int end_x,end_y;
int flag;
void dfs(int x,int y,int t){
if(t == T && x == end_x && y == end_y){
flag = 1;
return;
}
//printf("%d %d\n",x,y);
int temp = (T-t)-abs(x-end_x)-abs(y-end_y);
if(temp<0 || temp&1){//temp代表剩余的时间无法走完剩余的路程,temp&1是进行奇偶剪枝
flag = 0;
return;
}
for(int i = 0; i < 4; i++){
int xx = x + dx[i], yy = y + dy[i];
if(xx<0 || xx>=n || yy<0 || yy>=m)
continue;
if(maze[xx][yy] != 'X'){
maze[xx][yy] = 'X';
dfs(xx,yy,t+1);
maze[xx][yy] = '.';//别忘了深度优先遍历之后进行还原
}
if(flag)
break;
}
}
int main(){
while(scanf("%d%d%d",&n,&m,&T),n+m+T){
int wall = 0;
flag = 0;
for(int i = 0; i < n; i++)
scanf("%s",maze[i]);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++){
if(maze[i][j] == 'S'){
start_x = i;
start_y = j;
maze[i][j] = 'X';//要标记,不然会wrong
}
else if(maze[i][j] == 'D'){
end_x = i;
end_y = j;
}
else if(maze[i][j] == 'X')
wall++;
}
if(!(n*m-wall < T))
dfs(start_x,start_y,0);//剩下能走的路大于时间则进行剪枝
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}