ZOJ-1010 奇偶剪枝
题目描述: 判断在指定时间内dog是否能从制定开始位置走到制定结束位置。每走一步需要花费一个单位时间(秒).题目涉及奇偶剪枝及dfs
算法描述: 先判断在哪些条件下不可达,即找出所有可能的剪枝,然后从当前位置的四个方向分别回溯,找出到达制定门的最短路径
算法代码如下:
#include <iostream> #include <cmath> using namespace std; typedef struct cord { int x; int y; }Point; Point sp,ep;//sp:coordinate of start position,ep:coordinate of end position(door) const int MAX=7; char map[MAX][MAX]; bool bFlag = false; int numWall; int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; int N,M,T; int Dis(Point &p1, Point &p2) { return (abs(p1.x-p2.x)+abs(p1.y-p2.y)); } void dfs(Point startP,int t) { if(bFlag) return; if( t < Dis(startP,ep) || (t-Dis(startP,ep))%2) return; else if(t==0) { if(startP.x ==ep.x && startP.y == ep.y) { bFlag=true; return; } else return; } else { for(int i=0;i<4;++i) { Point tP; tP.x = startP.x+dir[i][0]; tP.y = startP.y+dir[i][1]; if(tP.x>=0 && tP.x < N && tP.y>=0 && tP.y < M && ( map[tP.x][tP.y] == '.' || map[tP.x][tP.y]=='D')) { map[tP.x][tP.y] = 'X';//mark it has been accessed dfs(tP,t-1); map[tP.x][tP.y] = '.';//backtrack } } } } int main() { while(cin>>N>>M>>T && N|M|T) { int i,j; numWall = 0; bFlag = false; for(i=0;i<N;++i) { for(j=0;j<M;++j) { cin>>map[i][j]; if(map[i][j] =='S') { sp.x = i; sp.y = j; } else if(map[i][j] =='D') { ep.x = i; ep.y = j; } else if(map[i][j] =='X') numWall++; } } if(N*M-numWall > T && Dis(sp,ep) <= T) //基本剪枝 { dfs(sp,T); } if(bFlag) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
作者:ballwql
本文为作者原创,版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。