杭电OJ 1010, 从非递归的DFS 到 剪枝

来源:互联网 发布:三体 死神永生 知乎 编辑:程序博客网 时间:2024/05/19 16:05

今天敲了一波杭电的1010,面对迷宫一类的题目,我留在印象中的就是用栈来解决。后来查阅了一下网上的解决方法,发现用的是DFS+剪枝算法,当然,就我的代码而言,单单采用栈来敲,是不能AC的。


从某种程度上来说,我的代码就是采用栈和一定的数据结构实现了递归的DFS所具备的功能。


废话不多说,先上代码





//每个位置的探索方向按顺序依次是(左(L),上(T),右(R),下(B))#include <iostream>#include <stack>#include <math.h>using namespace std;class Point   //定义点的数据结构{public:char prop;   //这个点上承载的是什么(D或者X或者.)char currentDirection;   //当前要探索的方向bool stakeState;    //目前在不在栈里面int x,y;Point(){x=0;y=0;prop='N';currentDirection='L';stakeState=false;}};int main(){Point A[100][100]={};stack<Point> B;int row=0;int column=0;int time=0;int sx,sy;  //初始点int ex,ey;  //终点int wall=0; //X的数量bool flag=false;std::cin>>row>>column>>time;while(!(row==0&&column==0&&time==0)){flag=false;wall=0;for(int i=0;i<row;i++){for(int j=0;j<column;j++){std::cin>>A[i][j].prop;A[i][j].x=i;A[i][j].y=j;A[i][j].currentDirection='L';A[i][j].stakeState=false;if(A[i][j].prop=='S'){sx=i;sy=j;}else if(A[i][j].prop=='D'){ex=i;ey=j;}else if(A[i][j].prop=='X')wall++;}}//剪枝,剪短程序运行时间if(((time-(abs(sx-ex)+abs(sy-ey)))%2!=0)||(time-(abs(sx-ex)+abs(sy-ey))<0)||row*column-wall<=time){cout<<"NO"<<endl;std::cin>>row>>column>>time;continue;}while(1){if(A[sx][sy].currentDirection=='L'){//下一个位置不能是越界、或者已经走过的位置(进栈了就是之间走过的)、或者障碍if(sy-1>=0&&A[sx][sy-1].stakeState==false&&A[sx][sy-1].prop!='X')  {time--;  //用掉1s走了一步if(A[sx][sy-1].prop=='D'&&time==0) //符合逃脱条件{flag=true;break;}A[sx][sy].currentDirection='T';  //设置该位置下一个待探索的方向A[sx][sy].stakeState=true;  //进栈B.push(A[sx][sy]);sy=sy-1;     //更新狗的当前位置}elseA[sx][sy].currentDirection='T';   //如果前面的条件不符合,直接探索当前位置的下一个方向}if(A[sx][sy].currentDirection=='T'){if(sx-1>=0&&A[sx-1][sy].stakeState==false&&A[sx-1][sy].prop!='X'){time--;if(A[sx-1][sy].prop=='D'&&time==0){flag=true;break;}A[sx][sy].currentDirection='R';A[sx][sy].stakeState=true;B.push(A[sx][sy]);sx=sx-1;}elseA[sx][sy].currentDirection='R';}if(A[sx][sy].currentDirection=='R'){if(sy+1<column&&A[sx][sy+1].stakeState==false&&A[sx][sy+1].prop!='X'){time--;if(A[sx][sy+1].prop=='D'&&time==0){flag=true;break;}A[sx][sy].currentDirection='B';A[sx][sy].stakeState=true;B.push(A[sx][sy]);sy=sy+1;}else A[sx][sy].currentDirection='B';}    if(A[sx][sy].currentDirection=='B'){if(sx+1<row&&A[sx+1][sy].stakeState==false&&A[sx+1][sy].prop!='X'){time--;if(A[sx+1][sy].prop=='D'&&time==0){flag=true;break;}A[sx][sy].currentDirection='Q';   //Q表示4个可能的方向都已经被探索完毕A[sx][sy].stakeState=true;B.push(A[sx][sy]);sx=sx+1;}elseA[sx][sy].currentDirection='Q';}//弹栈的条件(退回到上一个位置):当前位置没有可以探索的方向了或者时间用完当时没找到门(路没找对)或者//找到门了时间不对门没开(还是路不对)if(A[sx][sy].currentDirection=='Q'||(time==0)&&(A[sx][sy].prop!='D')||(time!=0)&&(A[sx][sy].prop=='D')){if(A[sx][sy].prop=='S')  //所有可能方向都试遍了{flag=false;break;   //出不去了}time++;//时间回退A[sx][sy].currentDirection='L';  //每个位置的可探索方向被重置(就是少了这个让我卡了好久)A[B.top().x][B.top().y].stakeState=false;sx=B.top().x;sy=B.top().y;B.pop();}}if(flag==false)cout<<"NO"<<endl;elsecout<<"YES"<<endl;cin>>row>>column>>time;}}

剪枝的问题不解决的话,是不能AC的!

剪枝问题在下属博客中讲的相当清楚:

http://www.cnblogs.com/newpanderking/archive/2012/10/09/2716984.html

0 0
原创粉丝点击