UVA816 紫书bfs

来源:互联网 发布:数据库包括哪些 编辑:程序博客网 时间:2024/05/18 17:55

本题比较困难的地方对于我来说应该是输入,后来参考了别人的代码原来还有stringstream这么好用的东西

还有就是方向的处理上面,lrj的方法比较巧妙,他是把方向全部转化成0-3然后一一对应数组中的元素 

#include<iostream>//不需要判断边界、移动方向已经确定#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<sstream>using namespace std;int r0,c0,r1,c1,r2,c2;///r0、c0表示出发坐标 r2、c2是终点坐标char dir0;///出发方向const int maxn=11;int has_edge[maxn][maxn][4][3],d[maxn][maxn][4];struct node{    int r,c,dir;///r行 c列 dir方向    node(int tr,int tc,int tdir)    {        r=tr;c=tc;dir=tdir;    }    node()    {    }};node p[maxn][maxn][4];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};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);}void print_ans(node u){    vector<node>nodes;    for(;;)    {        nodes.push_back(u);        if(d[u.r][u.c][u.dir]==0) break;        u=p[u.r][u.c][u.dir];    }    //打印解    int cnt=0;    for(int i=nodes.size()-1;i>=0;i--)    {        if(cnt%10==0) printf(" ");        printf(" (%d,%d)",nodes[i].r,nodes[i].c);        if(++cnt%10==0) printf("\n");    }    if(nodes.size()%10!=0) printf("\n");}void solve(){    int t=dir_id(dir0);    d[r0][c0][t]=0;    node temp(r0,c0,t);    d[r1][c1][t]=1;    node v(r1,c1,t);    p[r1][c1][t]= temp;    queue<node>q;    q.push(v);    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++)    {        if(has_edge[u.r][u.c][u.dir][i])        {            v=walk(u,i);            if(d[v.r][v.c][v.dir]<0)            {                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);            }        }    }    }    printf("  No Solution Possible\n");}int main(void){    string name,pos;    int r,c;    string str;    stringstream ss;    while(cin>>name&&name!="END")    {        cin>>r0>>c0>>dir0>>r2>>c2;        //计算进入迷宫的坐标        if(dir0=='N')      {r1=r0-1;c1=c0;}        else if(dir0=='E') {r1=r0;c1=c0+1;}        else if(dir0=='W') {r1=r0;c1=c0-1;}        else               {r1=r0+1;c1=c0;}        memset(d,-1,sizeof(d));        memset(has_edge,0,sizeof(has_edge));        memset(p,0,sizeof(p));        getchar();        while(getline(cin,pos)&&pos!="0")///将一整行输入存入pos        {            ss<<pos;            ss>>r>>c;///把ss中的整形提取出来赋值给r c            while(ss>>str)///从ss中抽取一个字符串            {                //cout<<"s:"<<str<<endl;                if(str[0]!='*')                {                int dir=dir_id(str[0]);                //cout<<"str+"<<str.size()<<endl;                for(int i=1;i<str.size();i++)                {                int turn=turn_id(str[i]);                has_edge[r][c][dir][turn]=1;                }                }            }            ss.clear();///记得清空        }        cout<<name<<"\n";        solve();    }    return 0;}


原创粉丝点击