【NOJ1044】【算法实验三】【BFS_分支限界】独轮车

2023-05-16


1044.独轮车

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

独轮车的轮子上有红、黄、蓝、白、绿(依顺时针序)5种颜色

在一个如下图所示的20*20的迷宫内每走一个格子,轮子上的颜色变化一次(原地转向则不变色

独轮车只能向前推或在原地转向。每走一格或原地转向90度均消耗一个单位时间。

现给定一个起点(S)和一个终点(T),求独轮车以轮子上的指定颜色(未指定车头朝向)到达终点所需的最短时间。

输入

本题包含一个测例。

测例中分别用一个大写字母表示方向和轮子的颜色,其对应关系为:E-东、S-南、W-西、N-北;R-红、Y-黄、B-蓝、W-白、G-绿。

在测试数据的第一行有以空格分隔的两个整数和两个大写字母,分别表示起点的坐标S(x,y)、轮子的颜色和开始的方向,

第二行有以空格分隔的两个整数和一个大写字母,表示终点的坐标T(x,y)和到达终点时轮子的颜色(不指定结束时方向)

从第三行开始的20行每行内包含20个字符,表示迷宫的状态。其中'X'表示建筑物,'.'表示路.

输出

在单独的一行内输出一个整数,即满足题目要求的最短时间。


第二版代码: 

#include <iostream>
#include <queue>

using namespace std;

//注:题中坐标从【1,1】开始
//但本代码中坐标从【0,0】开始
//因此对sx,sy,tx,ty都做了-1处理

/*****数据输入所需变量*****/
int sx,sy;
char sc,sd;

int tx,ty;
char tc;

char maze[20][20];
/***************************/

/******广搜所用数据结构********/
struct node
{
    int x;
    int y;
    int color;  //颜色,0-R-红,1-Y-黄,2-B-蓝,3-W-白,4-G-绿
    int dire;   //方向:0-E-东,1-S-南,2-W-西,3-N-北
};

node start,target;

queue <node> q1;

int used[20][20][5][4];
int time[20][20][5][4];

int walk[4][2]= //向前走一格的坐标变化
{
    0, +1,  //0-E-东
    +1, 0,  //1-S-南
    0, -1,  //2-W-西
    -1, 0   //3-N-北
};
/******************************/

/******函数声明********/
//输入数据函数
void input();

//初始化函数
void init();

//将代表颜色的字母转化为数字
int colorToInt(char c);

//将代表方向的字母转化为数字
int direToInt(char d);

//算法执行函数
int bfs();

//返回移动后的新节点(不保证有效)
node moveto(node now, int i);

//判断节点有效性
bool effective(node next);

//判断是否到达目标节点
bool isTarget(node next);
/***********************/

int main()
{
    input();
    init();
    cout<<bfs()<<endl;
    return 0;
}

//输入数据函数
void input()
{
    cin>>sx>>sy>>sc>>sd;
    cin.get();
    cin>>tx>>ty>>tc;
    cin.get();  //吃掉回车

    for(int i=0; i<20; i++)
    {
        for(int j=0; j<20; j++)
        {
            maze[i][j]=cin.get();
        }
        cin.get();  //吃掉回车
    }
}

//初始化函数
//因本题只有一个判例,而且本人巨懒
//故不初始化队列、判重数组、步数数组
void init()
{
    //设置初始节点
    start.x=sx-1;
    start.y=sy-1;
    start.color=colorToInt(sc);
    start.dire=direToInt(sd);

    //标记初始节点并入队
    used[start.x][start.y][start.color][start.dire]=1;
    q1.push(start);

    //设置目标节点
    target.x=tx-1;
    target.y=ty-1;
    target.color=colorToInt(tc);
}

//将代表颜色和方向的字母转化为数字
int colorToInt(char c)
{
    switch(c)
    {
        //关于颜色的转换
        case'R':return 0;
        case'Y':return 1;
        case'B':return 2;
        case'W':return 3;
        case'G':return 4;
    }
    return -1;
}

//将代表方向的字母转化为数字
int direToInt(char d)
{
    switch(d)
    {
        //关于方向的转换
        case'E':return 0;
        case'S':return 1;
        case'W':return 2;
        case'N':return 3;
    }
    return -1;
}

//算法执行函数
int bfs()
{
    node now,next;
    while(!q1.empty())
    {
        now=q1.front();
        q1.pop();

        for(int i=0; i<3; i++)  //0==向前走,1==原地左转,2==原地右转
        {
            next=moveto(now, i);    //移动后的新节点next
            if(effective(next))     //若有效
            {
                used[next.x][next.y][next.color][next.dire]=1;
                time[next.x][next.y][next.color][next.dire]=
                    1+time[now.x][now.y][now.color][now.dire];

                if(isTarget(next))  //判断是否到达目标
                {
                    return time[next.x][next.y][next.color][next.dire];
                }
                else    //若未到达目标则入队
                {
                    q1.push(next);
                }
            }
        }
    }
    return -1;
}

//返回移动后的新节点(不保证有效)
node moveto(node now, int i)
{
    node next;

    if(i==0)    //向前走一格
    {
        next.x=now.x+walk[now.dire][0];
        next.y=now.y+walk[now.dire][1];
        next.color=(now.color+1)%5;
        next.dire=now.dire;
    }
    else    //原地转向
    {
        next.x=now.x;
        next.y=now.y;
        next.color=now.color;
        if(i==1)    //左转
        {
            next.dire=(now.dire+4-1)%4;
        }
        else        //右转
        {
            next.dire=(now.dire+1)%4;
        }
    }
    return next;
}

//判断节点有效性
//无效条件:越界、撞墙、重复
bool effective(node next)
{
    if(next.x>=0&&next.x<20&&next.y>=0&&next.y<20)  //不越界
    {
        if(maze[next.x][next.y]!='X')   //不撞墙
        {
            if(!used[next.x][next.y][next.color][next.dire])    //不重复
            {
                return true;
            }
        }
    }
    return false;
}

//判断是否到达目标节点
bool isTarget(node next)
{
    if(next.x==target.x&&next.y==target.y&&next.color==target.color)
    {
        return true;
    }
    else
    {
        return false;
    }
}

【10月21日后记】

1.第二次做的时候,代码写的很顺利,但是,因为,过于自负,少看了一个条件(原地转向时该死的车轮不变色啊啊啊),直接导致dubug时间成倍延长QAAAAAAAQ,下次一定要认真审题!!!

2.感觉写bfs已经形成套路了,如果看我bfs的前几篇文章里的代码就能看出来,用的数据结构,变量,函数,判断条件其实就那么几个,bfs函数里的套路都是一样的,重构后的第二版代码比第一版少了一百来行,emmmmm,现在应该不算是又臭又长的代码了叭。

3.不说了去吃饭了我好饿。

4.如果csdn里的代码也可以像在cb里那样折叠就好了,像input,init这种函数没什么看的必要,但因为出现顺序还是要放在bfs函数前面,影响关键信息阅读。

【10月7日后记】

1.第一次感觉代码写的心力交瘁……累skr人……大概也不会有人看这么又臭又长的代码叭……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【NOJ1044】【算法实验三】【BFS_分支限界】独轮车 的相关文章

随机推荐

  • Unable to determine application id: com.android.tools.idea.run.ApkProvisionException: ERROR: APK pat

    Unable to determine application id com android tools idea run ApkProvisionException ERROR APK path is not specified for
  • Java获取文件的MD5

    Java获取文件的MD5 主要是通过读取文件的字符流 xff0c 然后赋值给MessageDigest对象 xff0c 最后将文件流转换成16进制的字符串 span class token keyword import span span
  • android整合好视通sdk经验总结(二)

    一 无法正常访问好视通服务接口 当按照android整合好视通sdk经验总结 xff08 一 xff09 步骤整合完毕后 xff0c 在这里修改申请的应用id和服务地址 修改完毕后运行发现无法正常初始化sdk xff0c 错误码30 xff
  • 视觉SLAM⑤--相机与图像

    目录 5 0 本章简介 5 1 相机模型 5 1 1针孔相机模型 5 1 2 畸变模型 5 1 3 双目相机模型 5 1 4 RGB D相机模型 5 2 图像 5 3 实践 xff1a 计算机中的图像 5 3 1 OpenCV的基本使用方法
  • 视觉SLAM⑩后端Ⅱ(滑动窗口滤波和优化与位姿图)

    目录 10 0 本章概述 10 1 滑动窗口滤波和优化 10 1 1 实际环境下的BA结构 10 1 2 滑动窗口法 10 2 位姿图 10 2 1 位姿图的意义 10 2 2位姿图的优化 10 3 非线性优化整体总结 xff1a 前端 后
  • 学习C++:C++进阶(五)CMake应用篇---集成第三方库和依赖管理

    目录 第二部分 xff1a 实用 CMake xff08 Practical CMake Getting Your Hands Dirty with CMake xff09 3 0 集成第三方库和依赖管理 xff08 Integrating
  • 2.ORB-SLAM2改进版本--稠密建图版本解析

    目录 1 修改思路 2 基本概念 nbsp 2 1 统计滤波 2 2 体素滤波
  • FreeRTOS 的命名规则

    初学 FreeRTOS 的用户对其变量和函数的命名比较迷惑 xff0c 下面专门做一下介绍 xff1a 变量 uint32 t 定义的变量都加上前缀 ul u 代表 unsigned 无符号 xff0c l 代表 long 长整型 uint
  • 【单目测距和双目测距比较】

    单目测距和双目测距比较 单 双目方案的优势与难点单目测距双目测距 双目测距实现步骤实现过程 单 双目方案的优势与难点 单目测距 优点 xff1a 单目的优势在于成本较低 xff0c 对计算资源的要求不高 xff0c 系统结构相对简单 缺点
  • ROS学习笔记(3):添加第三方依赖库

    最近在工控机上加入CAN卡 xff0c 想利用CAN卡来做为数据收发 现在在工程中加入CAN卡的头文件和自己做的cpp文档 已经申明了 函数 xff0c 但是还是会出现上图所示的错误 xff0c 经过一晚上的战斗算是搞清楚了 感谢 64 头
  • Java面试题及答案2019版(上)

    1 面向对象的特征有哪些方面 xff1f 答 xff1a 面向对象的特征主要有以下几个方面 xff1a 抽象 xff1a 抽象是将一类对象的共同特征总结出来构造类的过程 xff0c 包括数据抽象和行为抽象两方面 抽象只关注对象有哪些属性和行
  • git到远程出现的一些问题以及解决方法

    我们首先回顾一下 git reset命令 xff1a 1 git reset mixed xff1a 此为默认方式 xff0c 等同于不带任何参数的git reset 2 git reset soft 回退到某个版本 xff0c 只回退了c
  • CMakeLists.txt 和 package.xml 重要内容详解

    边学边看 xff0c 学到什么分享什么 CMakeLists txt 构建配置文件package xml 功能包配置文件 上面的意思个人理解就是功能包本身如果要在别处运行 xff0c 需要什么样的条件在xml文件中看 功能包自身 xff0c
  • Docker运行Prometheus(普罗米修斯)

    1 编辑yaml格式 xff0c 进行自我监控 mkdir etc prometheus cd etc prometheus vi etc prometheus prometheus yml global scrape interval 1
  • Kubernetes(k8s)安装Dashboard(控制面板)

    参考文章 xff1a https www jianshu com p f7ebd54ed0d1 1 默认情况下不会部署 Dashboard xff0c 可以通过以下命令部署 xff1a kubectl apply f https raw g
  • 航模无刷电机常见参数

    1 xff0c KV值 xff1a 表示电机运行速度的指标 xff0c 电机转速 61 KV值 x 工作电压 2 xff0c 空载电流 xff1a 指电机不带负载 xff08 螺旋桨等 xff09 时的额定工作电流 3 xff0c 电阻 x
  • RealSense D435i深度相机介绍

    文章目录 D435i硬件结构及各个组件原理详解前言一 硬件参数信息二 视觉处理器D4三 深度模块四 红外投影仪 Infrared Projector 五 彩色图像信号处理机 ISP 六 IMU D435i硬件结构及各个组件原理详解 前言 R
  • Ubuntu20.04下安装intel Realsense SDK

    1 安装安装依赖项 sudo apt span class token operator span get install libudev span class token operator span dev pkg span class
  • MiniFly的学习经历

    MiniFly的学习经历 基于MiniFly的无人机编队系统一台遥控器同步控制多台无人机无线通讯方面遥控代码部分无人机通信代码部分 一台遥控器分布控制多台无人机无人机控制部分 使用电脑的串口上位机控制无人机遥控串口通信接收指令指令设计 基于
  • 【NOJ1044】【算法实验三】【BFS_分支限界】独轮车

    1044 独轮车 时限 xff1a 1000ms 内存限制 xff1a 10000K 总时限 xff1a 3000ms 描述 独轮车的轮子上有红 黄 蓝 白 绿 xff08 依顺时针序 xff09 5种颜色 在一个如下图所示的20 20的迷