算法入门经典上面的题。题目链接 uva816

大致题意

有一个最多包含9*9个交叉点的迷宫。输入起点、离开起点时的朝向和终点,求一条最短路(多解时任意输出一个即可)。详细题意请看原题

思路

其实就是bfs,但是难点在于转向,将四个方向和3种转弯方式编号为0~3和0~2。

下面是转弯函数的实现

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

输入的时候读取交点的信息要注意处理。

利用has_edge[r][c][dir][turn]标记在坐标(r,c)处朝向dir转向turn能否成功。

AC代码

#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 bfs()
{
    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")
        {
            ss<<pos;
            ss>>r>>c;
            while(ss>>str)
            {
                if(str[0]!='*')
                {
                int dir=dir_id(str[0]);
                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";
        bfs();
    }
    return 0;
}

如有不当之处欢迎指出!

UVA 816 bfs的更多相关文章

  1. UVa 816 (BFS求最短路)

    /*816 - Abbott's Revenge ---代码完全参考刘汝佳算法入门经典 ---strchr() 用来查找某字符在字符串中首次出现的位置,其原型为:char * strchr (cons ...

  2. uva 816 BFS求最短路的经典问题……

    一开始情况没有考虑周全,直接WA掉了, 然后用fgets()出现了WA,给改成scanf就AC了 题目不是很难,用心就好…… #include <iostream> #include &l ...

  3. 【紫书】【重要】Abbott's Revenge UVA - 816 bfs 复杂模拟 带方向参数的迷宫

    题意:一个迷宫,每个交叉路口有一路标,限制了你从某方向进入该路口所能进入的路口. 题解:1.对于方向的处理:将node多增加一维dir,通过一个const 字符数组 加 上dir_id函数 以及一个方 ...

  4. UVA 816 - Abbott&#39;s Revenge(BFS)

    UVA 816 - Abbott's Revenge option=com_onlinejudge&Itemid=8&page=show_problem&category=59 ...

  5. UVA 816 -- Abbott's Revenge(BFS求最短路)

     UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...

  6. uva 816 - Abbott&#39;s Revenge(有点困难bfs迷宫称号)

    是典型的bfs,但是,这个问题的目的在于读取条件的困难,而不是简单地推断,需要找到一种方法来读取条件.还需要想办法去推断每一点不能满足条件,继续往下走. #include<cstdio> ...

  7. UVa 816 Abbott的复仇(BFS)

    寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了.希望以后每天也能多刷几道题. 题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同, ...

  8. BFS求最短路 Abbottt's Revenge UVa 816

    本题的题意是输入起点,朝向和终点,求一条最短路径(多解时任意输出一个即可) 本题的主要代码是bfs求解,就是以下代码中的slove的主要部分,通过起点按照路径的长度来寻找最短路径,输出最先到终点的一系 ...

  9. Abbott's Revenge UVA - 816 (输出bfs路径)

    题目链接:https://vjudge.net/problem/UVA-816 题目大意: 有一个最多包含9*9 个交叉点的迷宫.输入起点,离开起点时的朝向和终点,求一条最短路(多解时任意输出 一个即 ...

随机推荐

  1. Django_MTV视图

    WEB服务请求流程? 用户请求通过url,url带着用户的用户信息封装成request,然后服务器收到url请求,激活获取url中带来的request,服务器处理request逻辑后,返回封装好的re ...

  2. CSS3 三角形运用

      酷酷的 CSS3 三角形运用 概述 在早期的前端Web设计开发年代,完成一些页面元素时,我们必须要有专业的PS美工爸爸,由PS美工爸爸来切图,做一些圆角.阴影.锯齿或者一些小图标. 在CSS3出现 ...

  3. Servlet--取得初始化配置信息

    关于这块内容,主要就是玩一个接口:ServletConfig.先翻下API,了解一下. 定义: public interface ServletConfig 这个接口定义了一个对象,通过这个对象,Se ...

  4. form表单中enctype属性作用

    上传文件时,提交的表单属性里需要加enctype="multipart/form-data",才能提交文件信息,不然会报错.那么enctype属性的作用是什么?就是设置表单传输的编 ...

  5. hadoop - spark on yarn 集群搭建

    一.环境准备 1. 机器: 3 台虚拟机 机器 角色  l-qta3.sp.beta.cn0 NameNode,ResourceManager,spark的master l-querydiff1.sp ...

  6. Python爬虫进阶(Scrapy框架爬虫)

    准备工作:           配置环境问题什么的我昨天已经写了,那么今天直接安装三个库                        首先第一步:                           ...

  7. JMeter打开jmx文件报错解决方法

    错误提示: Error Problem loading XMLfrom:'D:\software\apace-jmeter-3.3\bin\线程组jmx', missing class com.tho ...

  8. jumpserver v0.4.0 基于 CenOS7 的安装详解

    标签(linux): jumpserver 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 笔者已经弃用Jumpserver,并自已开发了shell跳板机. sh ...

  9. 搭建内网的NTP时间服务器

    NTP时间服务器 标签: linux 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 1.简介 NTP(Network Time Protocol,网络时间协议) ...

  10. zookeeper 环境搭建

    1.准备三台服务器 ip分别为:192.168.100.128.192.168.100.129.192.168.100.133 a.修改主机名称 vi /etc/sysconfig/network 修 ...