Tempter of the Bone

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

题意: 输入一个n*m的迷宫,和一个T:可以在迷宫中生存的最大时间。S为起点,D为终点。并且,每个格子只能踩一次,且只能维持一秒,然后该块地板就会塌陷。所以你必须每秒走一步,且到D点时,所用时间为T。用深搜。

解题思路: 用深收,但是直接用深收会超时的,必须加上剪枝这里要用奇偶剪枝的方式,减少收索次数。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 char map[8][8]; //记录原来的地图
 7 bool visit[8][8];//标记该点是否被访问
 8 int n,m,t;
 9 int dx,dy,sx,sy;
10 bool flag;//标记是否找到目标
11 void dfs(int i,int j,int l)
12 {
13        if(flag) return ;//找到目标就返回 ,不用再往下找了
14        if(l>t) return ; //如果已经超出了时间就不用在找
15        if(i<1||i>n||j<1||j>m) return ; //如果已经超出了界限街不用再找
16        if(map[i][j]=='D'&&l==t) {flag=true; return ; }//找到目的地,就标记已经找到
17         int temp=abs(i-dx)+abs(j-dy);
18            temp=t-temp-l;   //如果到目的地的距离减去最短距离是奇数,就不用再找,因为这个是一定是偶数
19         if(temp&1) return ;//奇偶剪枝
20         if(!visit[i-1][j]&&map[i-1][j]!='X'){ //不是X就是D或者.
21              visit[i-1][j]=true;//标记当前的点已经找了
22              dfs(i-1,j,l+1);
23              visit[i-1][j]=false;//注意这里的改回来,否则下一次收索就会在已经改变的地图上收索了(自己犯过的错误)
24             }
25         if(!visit[i+1][j]&&map[i+1][j]!='X'){
26              visit[i+1][j]=true;
27              dfs(i+1,j,l+1);
28              visit[i+1][j]=false;
29             }
30         if(!visit[i][j+1]&&map[i][j+1]!='X'){
31              visit[i][j+1]=true;
32              dfs(i,j+1,l+1);
33              visit[i][j+1]=false;
34             }
35         if(!visit[i][j-1]&&map[i][j-1]!='X'){
36              visit[i][j-1]=true;
37              dfs(i,j-1,l+1);
38              visit[i][j-1]=false;
39             }
40 }
41 int main(){
42          int k; //统计x的个数,
43    while(~scanf("%d%d%d",&n,&m,&t)){
44         k=0;
45        memset(visit,false,sizeof(visit));//初始化一定要在这里,之前在下面初始化,结果错了
46       if(n==0||m==0||t==0)break;
47    for(int i=1;i<=n;i++){
48      for(int j=1;j<=m;j++){
49            cin>>map[i][j];
50           if(map[i][j]=='S'){
51                   sx=i;
52                   sy=j; //记录出发点的位子
53               visit[i][j]=true;//出发点一定是被标记的,开始时候忘了这里
54              }
55           if(map[i][j]=='D'){
56                   dx=i;
57                   dy=j; //记录目的地的位子
58               }
59           if(map[i][j]=='X')
60                 k++;
61           }
62     }
63               flag=false; //注意这里的初始化
64           if(n*m-k-1>=t)dfs(sx,sy,0); //如果剩余的.个数比t少,显然不能到达D,所以没必要dfs
65 
66           if(flag)
67                printf("YES
");
68             else
69                 printf("NO
");
70           }
71 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3366545.html