UVA-816 Abbott's Revenge (bfs)

17 篇文章 0 订阅


视频可算是做完了,可以敲题了


gg  我改了一天的这个题目,心痛到无法呼吸;

细节是挺麻烦的,但是思路是简单的,bfs

不过这个题目因为有方向,所以用了一个四维数组去存储这个点的状态是否存在,此点面朝z方向,向k方向是否可以行进;

对于路径的存储,是比较有新意的地方,用一个p数组去存储当前点的根,然后开始倒回去进行寻找路径


错误点1:

dfs的初点应该是起点面向方向直行之后的状态,不要直接用起点,因为有数据,起点是包含在内的

例:

MyMaze4
2 2 W 3 2
1 1 NR *
1 2 ER *
2 1 WR *
2 2 SF *
0

错误2:

可能是直接由起点到终点


#include <iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<queue>

using namespace std;
const int maxn=15;
string dirr="NESW";
string dire="FLR";
int dr[]={-1,0,1,0};
int dc[]={0,1,0,-1};

struct Node
{
    int r,c;
    int dir;
    Node(int rr=0,int cc=0,int di=0)
    {
        r=rr;c=cc;
        dir=di;
    }
    Node(const Node & s)
    {
        r=s.r;c=s.c;dir=s.dir;
    }
};
int d[maxn][maxn][maxn];
Node p[maxn][maxn][maxn];
int getok[maxn][maxn][maxn][maxn];
int have[maxn][maxn];
int r1,r2,dir0;
int r0,c0,rn,cn;
int maxx;
Node wall(Node s,int turn)
{
    int dir=s.dir;
    if(turn ==1) dir=(dir+3)%4;
    if(turn==2) dir=(dir+1)%4;
    return Node(s.r+dr[dir],s.c+dc[dir],dir);
}
int id_dirr(char s)
{
    for(int i=0;i<4;i++)
    {
        if(dirr[i]==s)
            return i;
    }
}
int id_dire(char s)
{
    for(int i=0;i<3;i++)
    {
        if(dire[i]==s)
            return i;
    }
}
void print(int si)
{
    vector<Node> h;
    h.clear();
    Node u(rn,cn,si);
    h.push_back(u);
    while(1)
    {
        Node q=p[u.r][u.c][u.dir];
        if(!d[q.r][q.c][q.dir])
         {   h.push_back(Node(q));
             break;
         }
        u=q;
        h.push_back(q);
    }
    int l=h.size();
    int ll=0;
    cout<<"  ";
     cout<<"("<<r0<<","<<c0<<") ";
    for(int i=l-1;i>=0;i--)
    {
        cout<<"("<<h[i].r<<","<<h[i].c<<")";//注意格式
        ll++;
        if(ll==l)
            cout<<endl;
        else if(ll%10==9)
            cout<<endl<<"  ";
        else
          cout<<" ";

    }
}
int inside(int r,int c)
{
    if(r<=0||c<=0||c>maxx||r>maxx)
        return 0;
    else
    return 1;
}
void bfs()
{
    queue<Node> q;
    Node qq=wall(Node(r0,c0,dir0),0);
    q.push(qq);
    d[qq.r][qq.c][qq.dir]=0;
    if(qq.r==rn&&qq.c==cn)
    {
        cout<<"  "<<"("<<r0<<","<<c0<<") "<<"("<<rn<<","<<cn<<")"<<endl;
    }
    else{
    //cout<<qq.r<<" "<<qq.c<<" "<<qq.dir<<endl;
    int flag=0;
    while(q.size())
    {
        Node u=q.front();
        q.pop();
        if(u.r==rn&&u.c==cn)
        {
            print(u.dir);
            flag=1;
           break;
        }
       for(int i=0;i<3;i++)
        {
            Node v=wall(u,i);
            //cout<<v.r<<" "<<v.c<<" "<<v.dir<<endl;
           // cout<<d[v.r][v.c][v.dir]<<" "<<getok[u.r][u.c][u.dir][i]<<" "<<inside(v.r,v.c)<<" "<<have[v.r][v.c]<<endl;
            if(d[v.r][v.c][v.dir]<0&&getok[u.r][u.c][u.dir][i]&&inside(v.r,v.c)&&have[v.r][v.c])
            {
                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);
            }
        }
    }
    if(!flag)
    printf("  No Solution Possible\n");
    }

}

int main()
{
    string s;
    //freopen("out.txt","w",stdout);
    while(cin>>s&&s!="END")
    {
        maxx=0;
        memset(p,0,sizeof(p));
        memset(d,0xff,sizeof(d));
        memset(getok,0,sizeof(getok));
        memset(have,0,sizeof(have));
        int r,c;

        char ch;
        string h;
        cin>>r0>>c0>>ch>>rn>>cn;
        dir0=id_dirr(ch);
        //cout<<dir0<<endl;
        have[r0][c0]=1;
        have[rn][cn]=1;
         maxx=max(maxx,r0);
        maxx=max(maxx,c0);
        maxx=max(maxx,rn);
        maxx=max(maxx,cn);
      //  getok[r0][c0][dir0][0]=1;
        while(cin>>r&&r)
        {
            cin>>c;
            maxx=max(maxx,r);
            maxx=max(maxx,c);
            have[r][c]=1;
            while(cin>>h&&h!="*")
            {
              int f1=id_dirr(h[0]);
              int f2;
              for(int i=1;i<h.size();i++)
              {
                  f2=id_dire(h[i]);
                 // cout<<f1<<" "<<f2<<endl;
                  getok[r][c][f1][f2]=1;
              }
            }

        }
        cout<<s<<endl;
        //cout<<"maxx"<<maxx<<endl;
        bfs();

    }
    return 0;
}


d


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值