UVA 816 bfs
来源:互联网 发布:yum 安装vim 编辑:程序博客网 时间:2024/05/18 03:13
算法入门经典上面的题。题目链接 uva816
大致题意
有一个最多包含9*9个交叉点的迷宫。输入起点、离开起点时的朝向和终点,求一条最短路(多解时任意输出一个即可)。详细题意请看原题
思路
其实就是bfs,但是难点在于转向,将四个方向和3种转弯方式编号为0~3和0~2。
下面是转弯函数的实现
const char *dirs="NESW"; const char *turns="FLR";int dir_id(char c) { return strchr(dirs,c)-dirs;}int turn_id(char c){ return strchr(turns,c)-turns;}const int dr[]={-1, 0, 1, 0};const int dc[]={ 0, 1, 0, -1};node walk(const node &u,int turn){ int dir=u.dir; if(turn==1) dir=(dir+3)%4; if(turn==2) dir=(dir+1)%4; return node(u.r+dr[dir],u.c+dc[dir],dir);}
输入的时候读取交点的信息要注意处理。
利用has_edge[r][c][dir][turn]标记在坐标(r,c)处朝向dir转向turn能否成功。
AC代码
#include<iostream>//不需要判断边界、移动方向已经确定 #include<cstdio>#include<cstring>#include<queue>#include<vector>#include<sstream> using namespace std;int r0,c0,r1,c1,r2,c2;//r0、c0表示出发坐标 r2、c2是终点坐标char dir0;//出发方向 const int maxn=11;int has_edge[maxn][maxn][4][3],d[maxn][maxn][4];struct node{ int r,c,dir;//r行 c列 dir方向 node(int tr,int tc,int tdir) { r=tr;c=tc;dir=tdir; } node() { }};node p[maxn][maxn][4];const char *dirs="NESW"; const char *turns="FLR";int dir_id(char c) { return strchr(dirs,c)-dirs;}int turn_id(char c){ return strchr(turns,c)-turns;}const int dr[]={-1, 0, 1, 0};const int dc[]={ 0, 1, 0, -1};node walk(const node &u,int turn){ int dir=u.dir; if(turn==1) dir=(dir+3)%4; if(turn==2) dir=(dir+1)%4; return node(u.r+dr[dir],u.c+dc[dir],dir);}void print_ans(node u){ vector<node>nodes; for(;;) { nodes.push_back(u); if(d[u.r][u.c][u.dir]==0) break; u=p[u.r][u.c][u.dir]; } //打印解 int cnt=0; for(int i=nodes.size()-1;i>=0;i--) { if(cnt%10==0) printf(" "); printf(" (%d,%d)",nodes[i].r,nodes[i].c); if(++cnt%10==0) printf("\n"); } if(nodes.size()%10!=0) printf("\n");}void bfs(){ int t=dir_id(dir0); d[r0][c0][t]=0; node temp(r0,c0,t); d[r1][c1][t]=1; node v(r1,c1,t); p[r1][c1][t]= temp; queue<node>q; q.push(v); while(!q.empty()) { node u=q.front(); q.pop(); if(u.r==r2&&u.c==c2) { print_ans(u); return; } for(int i=0;i<3;i++) { if(has_edge[u.r][u.c][u.dir][i]) { v=walk(u,i); if(d[v.r][v.c][v.dir]<0) { d[v.r][v.c][v.dir]=d[u.r][u.c][u.dir]+1; p[v.r][v.c][v.dir]=u; q.push(v); } } } } printf(" No Solution Possible\n");}int main(void){ string name,pos; int r,c; string str; stringstream ss; while(cin>>name&&name!="END") { cin>>r0>>c0>>dir0>>r2>>c2; //计算进入迷宫的坐标 if(dir0=='N') {r1=r0-1;c1=c0;} else if(dir0=='E') {r1=r0;c1=c0+1;} else if(dir0=='W') {r1=r0;c1=c0-1;} else {r1=r0+1;c1=c0;} memset(d,-1,sizeof(d)); memset(has_edge,0,sizeof(has_edge)); memset(p,0,sizeof(p)); getchar(); while(getline(cin,pos)&&pos!="0") { ss<<pos; ss>>r>>c; while(ss>>str) { if(str[0]!='*') { int dir=dir_id(str[0]); for(int i=1;i<str.size();i++) { int turn=turn_id(str[i]); has_edge[r][c][dir][turn]=1; } } } ss.clear(); } cout<<name<<"\n"; bfs(); } return 0;}
如有不当之处欢迎指出!
0 0
- uva 816 BFS迷宫
- UVA 816 bfs
- uva 816 Ancient Messages (BFS)
- UVA 816 - Abbott's Revenge(BFS)
- bfs Abbott的复仇 UVA 816
- uva 816 - Abbott's Revenge(bfs)
- uva 816 带方向的bfs
- UVA-816 Abbott's Revenge (bfs)
- uva 784(bfs)
- UVa 3721 - Islands 【bfs】
- uva 10603 倒水 bfs
- uva 10603 - Fill bfs
- uva 11624(BFS)
- uva 10047(BFS)
- UVA 11624 BFS Fire
- UVa Fire! 11624 (BFS)
- 双向BFS--Uva-11624
- UVA 10047 独轮车(BFS)
- 推荐系统itembase算法scala实现
- 多目录下,单makefile文档编程
- hduLucky7(容斥+中国剩余定理)
- springmvc SSM java redis shiro ehcache 整合
- C++头文件里编写实现代码
- UVA 816 bfs
- 自动化测试
- Android开发中常用到的一些工具类整理
- ros中launch文件
- harris角点
- java3线程答案
- tableau:柱图的两种实现方式
- POJ1837
- 怎样实现EDIUS中音频滤镜快速使用