Uva 816 Abbott's Revenge(BFS)
Posted sapphirebitter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Uva 816 Abbott's Revenge(BFS)相关的知识,希望对你有一定的参考价值。
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
struct Node
{
int row,col,dir;
Node(int row=0,int col=0,int dir=0):row(row),col(col),dir(dir){}
};
const char * dirs="NESW";
const char * turns="FLR";
const int maxn=10;
int have_way[maxn][maxn][4][3];///进入方向最多有4个,转弯方向最多有3个,最多是9*9的迷宫
int visit[maxn][maxn][4];///0为起点,-1表示未被访问,1表示路径中的点
Node pre[maxn][maxn][4];
int row0,col0, dir, row1, col1, row2, col2;
int dir_id(char c)
{
return strchr(dirs, c) - dirs;
}
int turn_id(char c)
{
return strchr(turns, c) - turns;
}
const int dirrow[] = {-1, 0, 1, 0};
const int dircol[] = {0, 1, 0, -1};
bool input()
{
char s[99],s2[99];
if(scanf("%s%d%d%s%d%d", s, &row0, &col0, s2, &row2, &col2) != 6) return false;///输入初始位置
printf("%s\n", s);
dir=dir_id(s2[0]);
row1 = row0 + dirrow[dir];
col1 = col0 + dircol[dir];
memset(have_way,0,sizeof(have_way));
for(;;)
{
int row, col;
scanf("%d",&row);
if(row==0) break;
scanf("%d",&col);
while(scanf("%s",s)==1&&s[0]!=‘*‘)
{
for(int i=1;i<strlen(s);i++)
have_way[row][col][dir_id(s[0])][turn_id(s[i])]=1;///输入每个点的进入方向及通行方向
}
}
return true;
}
bool inside(int row,int col)
{
return row >= 1 && row <= 9 && col >= 1 && col <= 9;
}
Node walk(Node t,int turn)
{
int dir=t.dir;
if(turn ==1) dir = (dir+3)%4;///按顺时针+3就是对应的转弯方向,即是向右
if(turn==2) dir=(dir+1)%4;///按顺时针+3就是对应的转弯方向,即是向左
return Node(t.row+dirrow[dir],t.col+dircol[dir],dir);
}
void print(Node u)
{
vector<Node> nodes;/// 从目标结点逆序追溯到初始结点
for(;;)
{
nodes.push_back(u);
if(visit[u.row][u.col][u.dir]==0) break;
u=pre[u.row][u.col][u.dir];
}
nodes.push_back(Node(row0,col0,dir));
int cnt = 0;
for(int i = nodes.size()-1; i >= 0; i--)/// 打印解,每行10个
{
if(cnt % 10 == 0) printf(" ");
printf(" (%d,%d)", nodes[i].row, nodes[i].col);
if(++cnt % 10 == 0) printf("\n");
}
if(nodes.size() % 10 != 0) printf("\n");
}
void run()
{
queue<Node> q;
memset(visit,-1,sizeof(visit));
Node u(row1, col1, dir);
visit[u.row][u.col][u.dir]=0;
q.push(u);
while(!q.empty())
{
Node u=q.front();
q.pop();
if(u.row == row2 && u.col == col2)///到达边界
{
print(u);
return;
}
for(int i = 0; i < 3; i++)///0~2表示前行,右转,左转
{
Node v = walk(u, i);
if(have_way[u.row][u.col][u.dir][i] && inside(v.row, v.col) && visit[v.row][v.col][v.dir] < 0)
{
visit[v.row][v.col][v.dir] = visit[u.row][u.col][u.dir] + 1;
pre[v.row][v.col][v.dir] = u;///记录前驱
q.push(v);
}
}
}
printf(" No Solution Possible\n");
}
int main()
{
while(input())
{
run();
}
return 0;
}
while(!q.empty())
{
Node u=q.front();
q.pop();
if(u.row == row2 && u.col == col2)///到达边界
{
print(u);
return;
}
for(int i = 0; i < 3; i++)///0~2表示前行,右转,左转
{
Node v = walk(u, i);
if(have_way[u.row][u.col][u.dir][i] && inside(v.row, v.col) && visit[v.row][v.col][v.dir] < 0)
{
visit[v.row][v.col][v.dir] = visit[u.row][u.col][u.dir] + 1;
pre[v.row][v.col][v.dir] = u;///记录前驱
q.push(v);
}
}
}
可作为BFS的模板
以上是关于Uva 816 Abbott's Revenge(BFS)的主要内容,如果未能解决你的问题,请参考以下文章