ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022.4.15 Uva816

2022-04-15 23:33:28  阅读:139  来源: 互联网

标签:node dirs 15 cout int Uva816 return 2022.4 dir


给出一个箭头迷宫,在每个路口处,如果你从某个方向进入了该路口,那么路口的地面上在靠近你的方向会画有一组箭头,它们相对于你的方向可以是向左,向前,向右,或者是它们的任意组合。

当你从某一方向进入某个入口时,下一步只能在这个入口对应方向上标记的箭头中选一个方向继续行进。在起点时,可以选择任何方向。

给出起点和终点,求它们之间的最短路径。

每条边的长度为1

 

 

 

这大概是我第一次做题时意识到语文的重要性 = =

乍一看就是普通的BFS,开始做才发现无从下手。题解也有很多看不懂的地方。

经过我的努力,写出了一个朴实无华的能过样例的题解。。。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=10;
int d[MAXN][MAXN][4];//用于记录BFS过程中节点的父节点
bool could[MAXN][MAXN][4][4];//用于标记在坐标ab并面向c时向d是否可以行走
char dirs[]="NESW";
char turns[]="FLR";
string named;//用于储存每组数据的地图名字
struct node
{
int r,c,dir;
};
node nown,start,fin;//分别代表当前、起点、终点
node lj[MAXN][MAXN][4];//记录bfs树的路径
int dr[]={-1,0,1,0};
int dc[]={0,1,0,-1};
//这里是为了将NEWS和FLR的信息转化成移动方向,通过上面的两数组一一对应。
inline int dir_id(char c){return strchr(dirs,c)-dirs;}
inline int turn_id(char c){return strchr(turns,c)-turns;}
bool input()
{
string dirs;
memset(could,0,sizeof(could));//每组数据初始化
char startdir;
cin>>named;
if(named=="END")
return false;
cin>>start.r>>start.c>>startdir>>fin.r>>fin.c;
nown.dir=dir_id(startdir);
//为了防止起始点重复以至于未开始就结束,先走一步.
nown.r=start.r+dr[nown.dir];
nown.c=start.c+dc[nown.dir];
int x,y;
while(cin>>x,x)//输入0结束
{
cin>>y;
while(cin>>dirs,dirs!="*")
{
for(int i=1;i<dirs.length();i++)
{
//cout<<x<<" "<<y<<" "<<turn_id(dirs[i])<<"\n";
could[x][y][dir_id(dirs[0])][turn_id(dirs[i])]=true;
}
}
}
return true;
}
inline bool pd(int r,int c)//判断越界
{
return r>0&&r<MAXN&&c>0&&c<MAXN;
}
node walk(const node &n,int turn)
{
node f;
int dir=n.dir;//直行时turn=0,无需操作,其余要根据NESW的顺序进行操作
if(turn==1)
dir=(dir+3)%4;//左转,即逆时针(相当于转三下)
if(turn==2)
dir=(dir+1)%4;//右转。即顺时针
f.r=n.r+dr[dir];f.c=n.c+dc[dir];f.dir=dir;
return f;
}
void print(node &n)
{
vector<node>bfstree;
while(1)//将起点之后的点一直到终点加入vector中。
{
bfstree.push_back(n);
if(!d[n.r][n.c][n.dir])
{
break;
}
n=lj[n.r][n.c][n.dir];
}
int cnt=0;
for(std::vector<node>::iterator i=bfstree.end()-1;
i>bfstree.begin();
i--)//倒序输出。
{
if(cnt%10){cout<<" ";}//在队首,输出一个空格
else {cout<<" ";}//否则两个
cout<<"("<<(*i).r<<","<<(*i).c<<")";
if(!(++cnt%10)) cout<<"\n";
}
if(cnt%10){cout<<" ";}
else {cout<<" ";}
cout<<"("<<start.r<<","<<start.c<<")";//不要忘记输出起点。
if(bfstree.size()%10)
cout<<"\n";
return;
}
void solve()
{
cout<<named<<"\n";
queue<node>Q;
memset(d,-1,sizeof(d));
node n=nown;
d[n.r][n.c][n.dir]=0;//从初始点走一步之后到达的点距离设为0
Q.push(n);
while(!Q.empty())//BFS
{
n=Q.front();
Q.pop();
if(n.r==fin.r&&n.c==fin.c)
{
print(n);
return;
}
for(int i=0;i<3;i++)//判断直走、左转、右转
{
//cout<<n.r<<" "<<n.c<<" "<<n.dir<<" "<<i<<endl;
if(could[n.r][n.c][n.dir][i])
{
node v=walk(n,i);
if(pd(v.r,v.c)&&d[v.r][v.c][v.dir]==-1)
{
d[v.r][v.c][v.dir]=d[n.r][n.c][n.dir]+1;
lj[v.r][v.c][v.dir]=n;
Q.push(v);
}
}
}
}
cout<<" No Solution Possible"<<"\n";
return;
}
int main()
{
std::ios::sync_with_stdio(false);
while(input())
{
solve();
};
return 0;
}

 

标签:node,dirs,15,cout,int,Uva816,return,2022.4,dir
来源: https://www.cnblogs.com/noname0974/p/16151479.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有