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 }