杭电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
- 杭电OJ 1010, 从非递归的DFS 到 剪枝
- 【杭电oj】1010 - Tempter of the Bone(dfs,奇偶剪枝,好题)
- hdu oj 1010 dfs+剪枝
- HDU OJ 1010 dfs+剪枝
- 杭电1518 Square(DFS+剪枝)
- 杭电ACM1010(dfs+剪枝)
- 【HDU 1864】 最大报销额 DP+剪枝+非递归dfs
- DFS的非递归写法
- hdu 1016 经典的dfs搜索 acm 杭电 OJ
- DFS所用到的奇偶剪枝
- 【杭电oj】2018-母牛的故事(递归)
- 杭电1010-奇偶剪枝
- Tempter of the Bone(杭电1010)(DFS+奇偶剪枝)
- 杭电1010——Tempter of the Bone(DFS、剪枝)
- 杭电1010Tempter of the Bone(dfs 奇偶剪枝)
- 杭电 1241 Oil Deposits 递归 DFS
- 图的DFS的非递归算法
- 【杭电-oj】-1196-二进制截止到非零位转换为十进制
- Break and Continue
- vs2010与oracle数据库连接
- Unity3D 游戏序列化及发布
- HTML-通过点击网页上的文字弹出QQ添加好友页面
- Spark函数讲解:collectAsMap
- 杭电OJ 1010, 从非递归的DFS 到 剪枝
- 百度之星2016初赛第一场(Astar Round 2A)
- vim折叠
- 感恩父母,不要等到子欲养而亲不待
- 共用体union
- android-项目目录的详细介绍
- grivade刷新success
- 大小端模式
- shell学习-特殊变量