您的位置:首页 > 其它

Abbott的复仇(Abbott's Revenge, ACM/ICPC World Finals 2000, UVa 816)<经典BFS>

2016-11-13 14:32 567 查看
the reason of failure:1、各种坑坑洼洼的修改。2、在第一个dir上,已经将其转换为数字了,就不该在计算时又转换一次

how to solve:对着正确的一遍又一遍找错误,最后自己不看答案完整写出

question:

where is difficult:

key point:1、BFS的使用方法。2、strchr的使用

(const char * dirs = "NESW";   //N开始顺时针 

const char * turns = "FLR"; 

int turn_id(char b){return strchr(turns,b)-turns;}

 int dir_id(char b){return strchr(dirs,b)-dirs;}) 根据输入的字母得转换成一个数字



3、在print()中每次u=p[u.r][u.c][u.dir];得到的值都不同,是由于赋值一次后指针的位置便改变了,

跟pos=a.begin();然后用pos插入到链表是一样的道理

my thinking: 题要多做才能熟练

#include<stdio.h>
#include <vector>
#include <queue>
#include<string.h>
#include <iostream>
using namespace std;

int r0,r1,r2,c0,c1,c2,a,b,dir;
char str1[10],str2[10],str3[10],str4[10];
const char * dirs = "NESW"; //N开始顺时针
const char * turns = "FLR";
int walked[10][10][10];
int dr[]={-1,0,1,0};
int dc[]={0,1,0,-1};
struct Node{
int r,c,dir;
Node(int rr,int cc,int dirr){ //这不是一个函数,这是一个变量赋值
r=rr;
c=cc;
dir=dirr;
}
Node(){};
};
Node p[10][10][4];
queue<Node>q;
int has_edge[10][10][10][10];
int turn_id(char b){return strchr(turns,b)-turns;}
int dir_id(char b){return strchr(dirs,b)-dirs;}
void print(Node u){
vector<Node>nodes;
while(1){
nodes.push_back(u);
if(walked[u.r][u.c][u.dir]==0) break;
u=p[u.r][u.c][u.dir];
//printf("%d%d%d ",u.r,u.c,u.dir);
//因为储存在地址里,每取一次地址就向前一步
}
nodes.push_back(Node(r0,c0,dir));
int cnt=0;
for(int i=nodes.size();i>=0;i--){
cout << "(" << nodes[i].r << "," << nodes[i].c << ")";
}
}
Node walk(Node &u,int c){
int dir1=u.dir;
if(c==1)dir1=(dir1+3)%4;
if(c==2)dir1=(dir1+1)%4;
return Node(u.r+dr[dir1],u.c+dc[dir1],dir1);
}
void solve(){
Node u(r1,c1,dir); //定义一个u,其为自定义结构体,赋初值r1,c1,dir
Node v;
memset(walked,-1,sizeof(walked));
walked[u.r][u.c][u.dir]=0;
q.push(u);
while(!q.empty()){
u=q.front();
q.pop();
r1=u.r;
c1=u.c;
if(r1==r2&&c1==c2) return print(u);
for(int j=0;j<3;j++){
v=walk(u,j);
if(walked[v.r][v.c][v.dir]<0&&has_edge[u.r][u.c][u.dir][j]){
walked[v.r][v.c][v.dir]=1;
p[v.r][v.c][v.dir]=u;
q.push(v);
}
}
}
}
int read(){
while(scanf("%s%d%d%s%d%d",str1,&r0,&c0,str2,&r2,&c2)!=6)return false;
printf("%s\n",str1);
dir=dir_id(str2[0]); //输入包括SAMPLE这个字符,然后是起始点与终点
r1=r0+dr[dir]; //根据方向,走第一步,上面已经将dir的值给转换为数字了,这里就不用再转换了
c1=c0+dc[dir];
while(scanf("%d",&a)==1&&a){ //输入数字,判断是否为0来判断是否还有点的信息没给出
scanf("%d",&b);
while(scanf("%s",str3)&&str3[0]!='*'){ //通过*判断是否输入的字符结束
int length=strlen(str3);
for(int i=1;i<length;i++){ //由于第一个字符是方向,所以只用输入后面的几个该方向能走的左右进去
has_edge[a][b][dir_id(str3[0])][turn_id(str3[i])]=1;
}
}
}
return true;
}
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while(read()){
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva bfs