HDU - 1010 Tempter of the Bone
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
#include <iostream> #include <cmath> #include <string.h> using namespace std; /**************************************************************************************************************** 题意: 找到图中规定起点和终点以及步数的路径,YES or NO 思路: 1,用了一下 BFS,结果懵逼了,因为没法做到规定步数。 2,因此用 DFS,核心在于(利用回溯可以找到每条路径,判断路径长度即可) 3,第一次见可以用回溯的~太方便的说。时间还可以优化,而我太渣了。。。 ****************************************************************************************************************/ char map[10][10]; int visit[10][10]; int flag,n,m,T; int id[4][2]={0,-1,0,1,1,0,-1,0}; int in_x,in_y,out_x,out_y; void dfs(int x,int y,int t) { if(flag || visit[x][y]) return ; //访问剪枝和找到结果剪枝 if(x>n || y>m || x<=0 || y<=0) return ; //边界剪枝 if(t == T && x == out_x && y == out_y) {flag=1; return ;} //找到结果 int temp = (T-t) - abs(x-out_x) - abs(y-out_y); if( temp < 0 || temp&1 ) return; //奇偶剪枝 visit[x][y]=1; for(int i = 0;i < 4;i ++){ int tx=x+id[i][0],ty=y+id[i][1]; if(map[tx][ty] != 'X' && !visit[tx][ty]){ dfs(tx,ty,t+1); visit[tx][ty]=0; //回溯,不懂为什么要回溯!!! } } } int main() { while(cin>>n>>m>>T) { memset(visit,0,sizeof(visit)); memset(map,'X',sizeof(map)); if(n == 0 && m == 0 && T == 0) break; int wall=0; for(int i = 1;i <= n;i ++){ for(int j = 1;j <= m;j ++){ cin>>map[i][j]; if(map[i][j] == 'S') {in_x=i;in_y=j;} else if(map[i][j] == 'D') {out_x=i;out_y=j;} else if(map[i][j] == 'X') wall++; } } if(n*m - wall <= T){ //我擦勒~~~这里简直是神优化! time: 468-78.这就是差距 cout<<"NO"<<endl; //也许是出题人给的数据的原因吧,如果空路的个数小于要求的步数,肯定到不了 continue; } flag=0; dfs(in_x,in_y,0); if(!flag) cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0; }