#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <string>
#include <queue>
#include <iostream>
using namespace std;
struct Node{
int x,y,dir;
Node(int xx,int yy,int dd){
x=xx;y=yy;dir=dd;
}
Node(){}
};
Node parents[10][10][4];//父亲结点,用于打出路径
bool has_edge[10][10][4][3];//保存是否有此行、列、面向、转向
int dist[10][10][4];//保存此结点的深度,可用于求最短路径的长度
int x0,y0,dir;//开始点
int x2,y2;//结束点
int x1,y1;//开始点的下一个点
int success;//是否有路标记
const char* directions = {"NESW"};//面向为北东南西
const char* turns = {"FLR"};//转向为直左右
int dir_id(char& c) { return strchr(directions,c)-directions; }
int turn_id(char& c) { return strchr(turns,c)-turns; }
int turnX[4]={-1,0,1,0};//根据面向的方向,计算下一步的坐标
int turnY[4]={0,1,0,-1};
bool inSide(int x,int y) { return x>0&&x<10&&y>0&&y<10; }
Node walk(Node& a,int t);
void bfs();
void print_path(Node top);
void printTest();
int main()
{
char caseName[21];
while(gets(caseName)&&strcmp(caseName,"END")!=0)
{
memset(has_edge,0,sizeof(has_edge));
success=0;
char tmpCh;
cin>>x0>>y0>>tmpCh>>x2>>y2;
dir=dir_id(tmpCh);
x1=x0+turnX[dir];
y1=y0+turnY[dir];
int x,y;
while(cin>>x && x!=0)
{
cin>>y;
char tmpStr[5];
while(cin>>tmpStr && tmpStr[0]!='*')
{
int dirID=dir_id(tmpStr[0]);
int len=strlen(tmpStr);
for(int i=1;i<len;i++)
has_edge[x][y][dirID][turn_id(tmpStr[i])] = 1;
}
}
//printTest();
getchar();//下一个循环有gets
printf("%s\n",caseName);
bfs();
if(success==0)
printf(" No Solution Possible\n");
}
return 0;
}
void print_path(Node top)
{
stack<Node> sk;
while(1)//遍历父亲,将结点逐个进栈,用dist判断退出循环条件,用parents判断难以处理出现相同结点问题
{
//printf("%d %d %c\n",top.x,top.y,directions[top.dir]);
//getchar();
sk.push(top);
if(dist[top.x][top.y][top.dir]==0){
sk.push(Node(x0,y0,dir));//开始点单独处理
break;
}
top=parents[top.x][top.y][top.dir];
}
int len=sk.size();
for(int sum=0;!sk.empty();)
{
if(sum%10==0)
printf(" ");
printf(" (%d,%d)",sk.top().x,sk.top().y);
sk.pop();
if(++sum%10==0)
printf("\n");
}
if(len%10!=0)
printf("\n");
}
void bfs()
{
queue<Node> queues;
memset(dist,-1,sizeof(dist));
memset(parents,0,sizeof(parents));
Node now(x1,y1,dir),top;
dist[now.x][now.y][now.dir]=0;
queues.push(now);
while(!queues.empty())
{
now=queues.front();
//printf("--%d %d %c\n",now.x,now.y,directions[now.dir]);
queues.pop();
if(now.x==x2&&now.y==y2){
print_path(now);
success=1;
return;
}
for(int i=0;i<3;i++){
top=walk(now,i);
if(has_edge[now.x][now.y][now.dir][i] && inSide(top.x,top.y) && dist[top.x][top.y][top.dir]<0){//now有此转向,且top在范围内,且top没有被访问
dist[top.x][top.y][top.dir]=dist[now.x][now.y][now.dir]+1;
parents[top.x][top.y][top.dir]=now;
queues.push(top);
}
}
}
}
Node walk(Node& a,int t)
{
Node tmp;
if(t==0) tmp.dir=a.dir;//直走方向不变
else if(t==1) tmp.dir=(a.dir+3)%4;//左转为逆时针
else if(t==2) tmp.dir=(a.dir+1)%4;//右转为顺时针
else printf("walk error\n");
tmp.x=a.x+turnX[tmp.dir];
tmp.y=a.y+turnY[tmp.dir];
return tmp;
}
void printTest()
{
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
for(int k=0;k<4;k++)
for(int l=0;l<3;l++)
if(has_edge[i][j][k][l])
printf("%d %d %c%c\n",i,j,directions[k],turns[l]);
}
UVa816
最新推荐文章于 2021-05-25 13:48:21 发布