您的位置:首页 > 其它

UVA816 Abbott's Revenge

2017-07-18 13:24 281 查看
vj上的题目链接:点击打开链接

最近在看刘汝佳的书,这题折腾了很久才理解

#include<stdio.h>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>

using namespace std;
int r0,c0,dir,rs,cs,r2,c2;
string mazeName;
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};
int d[15][15][15];//记录步数
struct Node{
int r,c,dir;
Node(int r=0,int c=0,int dir=0):r(r),c(c),dir(dir){}
};
Node p[15][15][15];//记录该点父结点

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);
}

int has_edge[15][15][15][15];//记录该情况是否可走

void read_edge(){
memset(has_edge,0,sizeof(has_edge));
int r,c,dir,turn;
string tmp;
while(cin>>r){
if(r==0) break;
cin>>c;
while(cin>>tmp){
if(tmp=="*") break;
dir=dir_id(tmp[0]);
for(int i=1;i<tmp.size();i++){
turn=turn_id(tmp[i]);
has_edge[r][c][dir][turn]=1;
}
}
}
}

bool read(){
cin>>mazeName;
if(mazeName=="END") return false;
char dir0;
cin>>r0>>c0>>dir0>>r2>>c2;
dir=dir_id(dir0);
rs=r0+dr[dir];
cs=c0+dc[dir];
read_edge();
return true;
}

bool inside(int r,int c){
if(r>=1&&r<=9&&c<=9&&c>=1) return true;
return false;
}

void print_ans(Node u){
vector<Node> v;
for(;;){
v.push_back(u);
if(d[u.r][u.c][u.dir]==0) break;
u=p[u.r][u.c][u.dir];
}
v.push_back(Node(r0,c0,dir));//起点入vector
cout<<mazeName<<endl;
int cnt=0;
for(int i=v.size()-1;i>=0;i--){
if(cnt%10==0) printf(" ");
printf(" (%d,%d)",v[i].r,v[i].c);
if(++cnt%10==0) printf("\n");
}
if(v.size()%10!=0) printf("\n");//不是10倍数的,要另外输换行
}

void solve(){
queue<Node> q;
memset(d,-1,sizeof(d));//d记录步数,因此初始化为-1
Node n(rs,cs,dir);
q.push(n);
d[n.r][n.c][n.dir]=0;
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++){
Node v=walk(u,i);
if(has_edge[u.r][u.c][u.dir][i]&&inside(v.r,v.c)&&d[v.r][v.c][v.dir]<0){//可从u这么走到v&&v在图内&&这个点没被走过,否则肯定不是最短
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);
}
}
}
cout<<mazeName<<endl;
printf("  No Solution Possible\n");
}

int main()
{
while(read()){
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: