概述
题意
最多有9*9个节点的迷宫, 这个迷宫特殊的是, 每个节点可走的方向是特定的. 比如 1 2 WLF * 这个指令的意思是若朝向西来到点(1,2), 可以选择左转或直走
思路
BFS
一开始用数组做的模拟, 上交RE了, 不知道原因是什么
学习紫书写法, 利用队列和结构体
AC代码
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
char name[25], str[10];
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//借助 strchr() 函数可以查找字符串s中首次出现字符c的位置这一功能将下列字母标序号
const char* ds = "NESW"; //标号为0-3 北东南西
const char* ts = "FLR"; //标号为0-2 直左右
int ds_id( char c ){ return strchr(ds, c) - ds; }
int ts_id( char c ){ return strchr(ts, c) - ts; }
int x1, y1, x2, y2, t;
char tt;
struct Node{
int x, y, a;
Node(int x = 0, int y = 0, int a = 0):x(x),y(y),a(a){}
};
bool judge[10][10][5][5], pla[10][10];
int vis[10][10][5];
Node pre[10][10][5];
void PRINT( Node u ){
vector<Node> n;
for(;;){
n.push_back(u);
if( vis[u.x][u.y][u.a] == 0 ) break;
u = pre[u.x][u.y][u.a];
}
n.push_back(Node(x1,y1,t));
int cnt = 0;
for( int i = n.size()-1; i >= 0; i-- ){
cnt++;
if( cnt % 10 == 1 ) printf(" ");
printf(" (%d,%d)",n[i].x, n[i].y);
if( cnt % 10 == 0 || i == 0 ) putchar('n');
}
}
Node getv( Node u, int i ){ //i=0:直走,方向不变, i=1:左转, i=2:右转
int a = u.a;
if( i == 1 ) a = u.a-1 < 0 ? 3 : u.a-1;
else if( i == 2 ) a = u.a+1 > 3 ? 0 : u.a+1;
return Node(u.x+dir[a][0], u.y+dir[a][1], a );
}
void bfs()
{
queue<Node> q;
Node u(x1 + dir[t][0], y1 + dir[t][1], t);
vis[u.x][u.y][u.a] = 0;
q.push(u);
while( !q.empty() ){
Node u = q.front();
q.pop();
if( u.x == x2 && u.y == y2 ){
PRINT(u);
return;
}
for( int i = 0; i < 3; i++ ){
Node v = getv(u, i);
if( judge[u.x][u.y][u.a][i] && vis[v.x][v.y][v.a] < 0 && pla[v.x][v.y] ){
vis[v.x][v.y][v.a] = vis[u.x][u.y][u.a] + 1;
pre[v.x][v.y][v.a] = u;
q.push(v);
}
}
}
printf(" No Solution Possiblen");
return;
}
void readin()
{
scanf("%d%d %c %d%d",&x1, &y1, &tt, &x2, &y2);
pla[x1][y1] = true;
pla[x2][y2] = true;
t = ds_id(tt);
int aa, bb;
while( scanf("%d",&aa) && aa){
scanf("%d",&bb);
pla[aa][bb] = true;
while( scanf("%s",str) && strcmp(str, "*") != 0 ){
int len = strlen(str);
for( int i = 1; i < len; i++ )
judge[aa][bb][ds_id(str[0])][ts_id(str[i])] = true;
}
}
}
void solve()
{
memset(judge, 0, sizeof(judge));
memset(vis, -1, sizeof(vis));
memset(pla, 0, sizeof(pla));
readin();
printf("%sn",name);
bfs();
}
int main()
{
while( ~scanf("%s",name) && strcmp(name, "END") != 0 )
solve();
return 0;
}
RE代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 10000;
char name[25], str[10];
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int pre[maxn];
//借助 strchr() 函数可以查找字符串s中首次出现字符c的位置这一功能将下列字母标序号
const char* ds = "NESW"; //标号为0-3 北东南西
const char* ts = "FLR"; //标号为0-2 直左右
int ds_id( char c ){ return strchr(ds, c) - ds; }
int ts_id( char c ){ return strchr(ts, c) - ts; }
int x1, y1, x2, y2, t;
char tt;
bool flag;
struct Node{ int x, y, a; };
Node p[maxn];
bool judge[10][10][5][5], vis[10][10][5], pla[10][10];
int cnt = 0;
void PRINT( int a ){
int t = pre[a];
if( t != 0 )
PRINT(t);
else{
printf(" (%d,%d)",x1, y1);
printf(" (%d,%d)",p[0].x, p[0].y);
cnt += 2;
}
printf(" (%d,%d)",p[a].x, p[a].y);
cnt += 1;
if( cnt % 10 == 0 ) putchar('n');
}
void bfs()
{
int head = 0, tail = 1, m, n, o, mm, nn, oo;
p[0].x = x1 + dir[t][0], p[0].y = y1 + dir[t][1], p[0].a = t;
pre[0] = -1;
while( head < tail ){
m = p[head].x, n = p[head].y, o = p[head].a;
//cout << m << ' ' << n << ' ' << o << endl;
if( m == x2 && n == y2 ){
PRINT(head);
flag = true;
return;
}
for( int i = 0; i < 3; i++ ){
if( judge[m][n][o][i] ){ //i=0:直走,方向不变, i=1:左转, i=2:右转
if( i == 0 ) oo = o;
else if( i == 1 ) oo = o-1 < 0 ? 3 : o-1;
else if( i == 2 ) oo = o+1 > 3 ? 0 : o+1;
mm = m + dir[oo][0];
nn = n + dir[oo][1];
}
if( !vis[mm][nn][oo] && pla[mm][nn] ){
//cout << mm << ' ' << nn << ' ' << endl;
vis[mm][nn][oo] = true;
p[tail].x = mm;
p[tail].y = nn;
p[tail].a = oo;
pre[tail] = head;
tail++;
}
}
head++;
}
return;
}
void readin()
{
scanf("%d%d %c %d%d",&x1, &y1, &tt, &x2, &y2);
pla[x1][y1] = true;
pla[x2][y2] = true;
t = ds_id(tt);
int aa, bb;
while( scanf("%d",&aa) && aa){
scanf("%d",&bb);
pla[aa][bb] = true;
while( scanf("%s",str) && strcmp(str, "*") != 0 ){
int len = strlen(str);
for( int i = 1; i < len; i++ )
judge[aa][bb][ds_id(str[0])][ts_id(str[i])] = true;
}
}
}
void solve()
{
memset(judge, 0, sizeof(judge));
memset(vis, 0, sizeof(vis));
memset(pla, 0, sizeof(pla));
flag = false;
readin();
printf("%sn",name);
bfs();
if( !flag ) printf(" No Solution Possible");
putchar('n');
}
int main()
{
while( ~scanf("%s",name) && strcmp(name, "END") != 0 )
solve();
return 0;
}
转载于:https://www.cnblogs.com/JinxiSui/p/9740596.html
最后
以上就是英俊皮皮虾为你收集整理的UVa 816 - Abbott's Revenge ( BFS )AC代码RE代码的全部内容,希望文章能够帮你解决UVa 816 - Abbott's Revenge ( BFS )AC代码RE代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复