hdu-1010 Tempter of the Bone

来源:互联网 发布:php base64解码 乱码 编辑:程序博客网 时间:2024/05/17 07:07

http://acm.hdu.edu.cn/showproblem.php?pid=1010

题意:在n*m的地图上,标记为S的为狗狗的起点,D为门,问能否恰好以给定t的时间到达D,能就输出YES,否则NO,每个点只能走一次。

思路:dfs问题,找到一条长度恰好为t的路径,不一定是最短路路径,所以不能单纯用bfs。

但是  一般dfs会超时,所以要剪枝,这里主要用到奇偶性剪枝,参考链接:

http://baike.baidu.com/view/7789287.htm?fr=alad

http://www.slyar.com/blog/depth-first-search-even-odd-pruning.html

下面是优化后的代码:46ms

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;char map[9][9];int n,m,t,di,dj;bool escape;int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};void dfs(int si,int sj,int cnt){   if(cnt>10000) return;   if(escape) return;   if(si>n||sj>m||si<=0||sj<=0) return;   if(cnt==t&&si==di&&sj==dj)    escape=1;  //找到恰好为t的路径   if(escape) return;   if(cnt>=t) return; //如果当前步数比t大   int i,temp;   temp=(t-cnt)-abs(si-di)-abs(sj-dj); //奇偶性剪枝,t-cnt是表示剩余的步数,后面两个绝对值之和是表示当前点到终点的最短路径   if(temp<0||temp&1) return;            //结果不能小于0或者为基数,因为上面的差一定为偶数才有解。   for(i=0;i<4;i++){      if(map[si+dir[i][0]][sj+dir[i][1]]!='X')      {         map[si+dir[i][0]][sj+dir[i][1]]='X';         dfs(si+dir[i][0],sj+dir[i][1],cnt+1);         map[si+dir[i][0]][sj+dir[i][1]]='.';      }   }   return;}int main(){    int i,j,si,sj;    while(cin>>n>>m>>t)    {      if(n==0&&m==0&&t==0) break;      int wall=0;      for(i=1;i<=n;i++)         for(j=1;j<=m;j++)         {            cin>>map[i][j];            if(map[i][j]=='S') { si=i; sj=j; }            else if(map[i][j]=='D') { di=i; dj=j; }            else if(map[i][j]=='X') wall++;         }       if(n*m-wall<=t) //如果地图全部能够走的步数加起来都小于等于t,表示一定不能达到。       {           cout<<"NO"<<endl;           continue;       }       escape=0;       map[si][sj]='X';       dfs(si,sj,0);       if(escape) cout<<"YES"<<endl;       else cout<<"NO"<<endl;   }   return 0;}


 

0 0
原创粉丝点击