UVA816 三状态BFS

UVA816 三状态BFS

UVA816
题目是一个标准的求最短路问题,但是多了一个朝向。也就是说不同的朝向进入一个节点,转换方向的方法各不相同。所以我们对于每个节点出了横纵坐标以外,还要多一个维度记录朝向。
定义节点数组p[y][x][dir]记录(y,x)坐标,朝向为dir的节点的前继节点。

#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");
    }
   大专栏  UVA816 三状态BFS  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 Possiblen");
}

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

原文地址:https://www.cnblogs.com/liuzhongrong/p/12289310.html

时间: 2024-10-09 19:57:06

UVA816 三状态BFS的相关文章

Rhythmk 学习 Hibernate 02 - Hibernate 之 瞬时状态 离线状态 持久化状态 三状态

by:rhythmk.cnblogs.com 1.Hibernate 三种状态: 1.1.三种定义(个人理解,不一定准确):  瞬时状态(transient):    不被session接管,且不存在数据库中的对象的状态,类似于新New一个对象  离线状态 (detached):    数据库中存在而不被session接管  持久化状态(persistent): 对象被session管理且数据库中存在此对象 1.2. 状态之间转换关系图 2 .状态转换以及Hibernate数据库执行过程详解:

搜索(另类状态BFS):NOIP 华容道

描述 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间. 小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的: 在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的: 有些棋子是固定的,有些棋子则是可以移动的: 任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白

uva1660_巡逻的机器人(状态bfs)

/////////////////////////////////////////////////////////////////////////////////////////////////////// 作者:tt2767 声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 查看本文更新与讨论请点击:http://blog.csdn.net/tt2767 链接被删请百度: CSDN tt2767 ///////////////

Flex tree加三状态的Checkbox

网上有下过其它人的实现的样例.可是样式不好改.还有就是不能初始化选中,还有三态效果那个半选中状态也是不清楚.所以自己依据Itemrender搞了一个,还凑合 效果如图:全选和半选状态,Checkbox的flex3的样式用的图片 TreeCheckboxItemRender.mxml <? xml version="1.0" encoding="utf-8"?> <s:MXTreeItemRenderer xmlns:fx="http://

线程的五种状态及改变状态的三种方法

1.新状态:线程对象已经创建,还没有在其上调用start()方法. 2.可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态.当start()方法调用时,线程首先进入可运行状态.在线程运行之后或者从阻塞.等待或睡眠状态回来后,也返回到可运行状态. 3.运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态.这也是线程进入运行状态的唯一一种方式. 4.等待/阻塞/睡眠状态:这是线程有资格运行时它所处的状态.实际上这个三状态组合为一种,其共同点是:线程

Java线程状态的改变

一.线程状态 线程的状态转换是线程控制的基础.线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新状态:线程对象已经创建,还没有在其上调用start()方法. 2.可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态.当start()方法调用时,线程首先进入可运行状态.在线程运行之后或者从阻塞.等待或睡眠状态回来后,也返回到可运行状态. 3.运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态.这也是线

Codeforces Gym 100187E E. Two Labyrinths bfs

E. Two Labyrinths Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/E Description A labyrinth is the rectangular grid, each of the cells of which is either free or wall, and it's possible to move only between free

Java线程:线程状态的转换

Java线程:线程状态的转换 一.线程状态 线程的状态转换是线程控制的基础.线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新状态:线程对象已经创建,还没有在其上调用start()方法. 2.可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态.当start()方法调用时,线程首先进入可运行状态.在线程运行之后或者从阻塞.等待或睡眠状态回来后,也返回到可运行状态. 3.运行状态:线程调度程序从可运行池中选择一个线程作为当前

服务器响应的生成:HTTP状态代码——HttpServletResponse接口应用

一 HTTP响应的格式              web服务器对客户端的响应一般包含:一个状态行,一些响应报头,一个空行和相应的文档构成.               1,状态行: 状态行由HTTP版本,一个状态代码以及一段对应状态代码的简短消息组成,表示请求是否被理解或被满足.HTTP版本由服务器决定.状态码一般由系统自动设置为200.也可以用Servlet设置状态码.消息巍峨自定义. 2,响应报. 3,空行 4,文档 二 如何设置状态代码 在向客户程序发送任何文档内容之前调用方法设置状态代码