P3855 [TJOI2008] Binary Land

news2024/9/20 9:28:22

[TJOI2008] Binary Land

题目背景

Binary Land是一款任天堂红白机上的经典游戏,讲述的是两只相爱的企鹅Gurin和Malon的故事。两只企鹅在一个封闭的迷宫中,你可以控制他们向上下左右四个方向移动。但是他们的移动有一个奇怪的规则,即如果你按“上”或“下”方向键,两只企鹅会同时向上移动或向下移动1格;如果你按“左”方向键,则Malon向左移动1格,同时Gurin向右移动1格;如果你按“右”方向键,则Malon向右移动1格,Gurin向左移动1格。当然,如果某只企鹅被障碍挡住,它就不会移动了。另外,在迷宫的某些格子处有蜘蛛网,如果任何一只企鹅进入这种格子,则游戏失败。两只企鹅不会相互阻挡,即在相向运动时他们可以“穿过”彼此,也可以同时处于同一格子里。迷宫的某个格子上有一颗红心,游戏的任务就是使两只企鹅同时到达这个格子。

题目描述

请编写程序找出完成任务所需的最少的操作步数。如果无法完成目标,输出“no”。

输入格式

第一行包含两个整数R, C 表示迷宫的长和宽。

按下来有R行,每行包含C个字符,描述了一个迷宫。其中’#’表示企鹅不能通过的障碍物,’X’表示蜘蛛网,’.’表示空地,’G’表示Gurin的初始位置,’M’表示Malon的初始位置,’T’表示终点位置。

输入数据保证标有’G’,’M’,’T’的格子分别只有一个,保证企鹅不可能走到迷宫以外。

输出格式

输出只有一行,为最少的操作步数。如果不能完成任务,输出“no”。

样例 #1

样例输入 #1

4 7
#######
#..T..#
#G##M##
#######

样例输出 #1

4

提示

满足要求的一个操作序列为:上-右-左-左

3 ≤ R, C ≤ 30

分析

使用bfs即可,开结构体需记录两只企鹅的坐标,当然还有操作步数

代码

#include <bits/stdc++.h>
using namespace std;
const int M = 35;
int  r, c;
bool st[M][M][M][M];
char g[M][M];
struct point {
    int x1, y1;
    int x2, y2;
    int u;
    point(int x1=0, int y1=0, int x2=0, int y2=0,int u=0) :x1(x1), y1(y1), x2(x2), y2(y2),u(u) {}
};
queue<point> q;
int lsx, lsy;
point read() {
    point fi;
    cin >> r >> c;
    memset(st, false, sizeof(st));
    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= c; j++) {
            char& tmp = g[i][j];
            cin >> tmp;
            if (tmp == 'G') fi.x1 = i, fi.y1 = j;
            if (tmp == 'M') fi.x2 = i, fi.y2 = j;
            if (tmp == 'T') lsx = i, lsy = j;
        }
    st[fi.x1][fi.y1][fi.x2][fi.y2] = 1;
    fi.u = 0;
    return fi;
}
int check(point t) {
    if (g[t.x1][t.y1] == 'X' or g[t.x2][t.y2] == 'X') return -1;
    if (g[t.x1][t.y1] == '#' and g[t.x2][t.y2] == '#') return -1;
    if (g[t.x1][t.y1] == '#') return 1;
    if (g[t.x2][t.y2] == '#') return 2;
    return 0;
}
void update1(point t, int i) {
    point u(t);
    u.x1 += i; u.x2 += i; bool f = 1; u.u++;
    switch (check(u))
    {
    case 1: {u.x1-=i; break; }
    case 2: {u.x2-=i; break; }
    case 0: {break; }
    default: {f = 0; break; } 
    }
    if (f and !st[u.x1][u.y1][u.x2][u.y2]) q.push(u), st[u.x1][u.y1][u.x2][u.y2] =  1;
}
void updw(point t) {
    update1(t, 1);
    update1(t, -1);
}
void update2(point t, int i,int j) {
    point u(t);
    u.y1 += i; u.y2 += j; bool f = 1; u.u++;
    switch (check(u))
    {
    case 1: {u.y1 -= i; break; }
    case 2: {u.y2 -= j; break; }
    case 0: {break; }
    default: {f = 0; break; }
    }
    if (f and !st[u.x1][u.y1][u.x2][u.y2]) q.push(u), st[u.x1][u.y1][u.x2][u.y2] = 1;
}
void lfrg(point t) {
    update2(t, 1, -1);
    update2(t, -1, 1);
}
int bfs() {
    q.push(read());
    while (!q.empty()) {
        point now = q.front(); q.pop();
        if (now.x1 == lsx and now.x2 == lsx and now.y1 == lsy and now.y2 == lsy) return now.u;
        updw(now);
        lfrg(now);
    }
    return -1;
}

int main() {
    int ans = bfs();
    if (ans == -1) cout << "no";
    else cout << ans;
    return 0;
}

代码分析

代码较长,分多部分看
1.bfs

int bfs() {
    q.push(read());
    while (!q.empty()) {
        point now = q.front(); q.pop();
        if (now.x1 == lsx and now.x2 == lsx and now.y1 == lsy and now.y2 == lsy) return now.u;
        updw(now);
        lfrg(now);
    }
    return -1;
}

基本的bfs,取队头后再入队其他的值,其中updw(now); lfrg(now);函数的作用分别为尝试上下移动,尝试左右移动
2.updw/lfrg
这两个函数每个都代表了两种操作
由于基本相同,我们只看上下移动的:

void update1(point t, int i) {
    point u(t);
    u.x1 += i; u.x2 += i; bool f = 1; u.u++;
    switch (check(u))
    {
    case 1: {u.x1-=i; break; }
    case 2: {u.x2-=i; break; }
    case 0: {break; }
    default: {f = 0; break; } 
    }
    if (f and !st[u.x1][u.y1][u.x2][u.y2]) q.push(u), st[u.x1][u.y1][u.x2][u.y2] =  1;
}

这是updw函数中调用的函数
首先,我们使状态t进行上下移动,更新步数,后调用check,判断是否合法,此时分4种情况

int check(point t) {
    if (g[t.x1][t.y1] == 'X' or g[t.x2][t.y2] == 'X') return -1;
    if (g[t.x1][t.y1] == '#' and g[t.x2][t.y2] == '#') return -1;
    if (g[t.x1][t.y1] == '#') return 1;
    if (g[t.x2][t.y2] == '#') return 2;
    return 0;
}

return 1: 代表第一只企鹅非法移动,所以撤销移动
return 2:同理,第二只企鹅非法移动
return 0:都是合法移动
return -1:都不合法或不存在此状态
最后入队即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/822063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【技术讨论】RF环境搭建手册

简要整理下环境搭建的步骤&#xff0c;以便快速、准确的搭建测试环境。 一、环境搭建 一、Python 2.7 1、 不要用Python3.6&#xff0c;很多库3.6中还没有&#xff0c;wxPython官方只支持Python 2。 2、 环境变量配置后需要重启才能生效。 3、 环境变量添加C:\Python27\Sc…

k8s概念-deployment

deployment用于部署无状态应用 Deployment集成了上线部署、滚动升级、创建副本、回滚等功能 Deployment里包含并使用了ReplicaSet Replicaset 通过改变Pod副本数量实现Pod的扩容和缩容 参考文档 https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/ …

go Channel

channel 单纯地将函数并发执行是没有意义的。函数与函数之间需要交换数据才能体现出并发执行函数的意义。 虽然可以使用共享内存进行数据交换&#xff0c;但是共享内存在不同的goroutine中很容易发生竞态问题。为了保证数据交换的准确性&#xff0c;必须使用互斥量对内存进行…

ptyhon——案例五:设定:list=[0,1,2,3,4,5] 列表,翻转列表

案例五&#xff1a;设定&#xff1a;list[0,1,2,3,4,5] 列表&#xff0c;翻转列表def Reverse(lst):return [ele for ele in reversed(lst)] #翻转列表 lst[0,1,2,3,4,5] print(Reverse(lst))

insert into select用法

文章目录 一、insert into select二、insert into select插入失败 本篇文章主要讲解insert into select 的用法&#xff0c;以及insert into select的坑或者注意事项。本篇文章中的sql基于mysql8.0进行讲解 一、insert into select 该语法常用于从另一张表查询数据插入到某表中…

hcip——BGP实验

要求 1.搭建toop 2.地址规划 路由器AS接口地址R11 loop0:1.1.1.1 24 loop1 : 192.168.1.1 24 g0/0/0 12.0.0.1 24 R22 64512 g0/0/0: 12.0.0.2 24 g/0/01: 172.16.0.2 19 g0/0/2: 172.16.96.2 19 R32 64512g0/0/0: 172.16.0.3 19 g0/0/1:1…

【LeetCode】88. 合并两个有序数组

这道题我总共想了三种解法。 1.将nums2中的元素依次放入nums1有效元素的后面&#xff0c;再总体进行排序。 import java.util.*; class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int j 0;for(int i m;i<mn;i){nums1[i] nums2[j];j;}Arrays…

【PostgreSQL】系列之 一 CentOS 7安装PGSQL15版本(一)

目录 一、何为PostgreSQL&#xff1f; 二、PostgreSQL安装 2.1安装依赖 2.2 执行安装 2.3 数据库初始化 2.4 配置环境变量 2.5 创建数据库 2.6 配置远程 2.7 测试远程 三、常用命令 四、用户创建和数据库权限 一、何为PostgreSQL&#xff1f; PostgreSQL是以加州大学…

2023.08.01 驱动开发day8

驱动层 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/of_gpio.h>#…

【从零开始学习JAVA | 三十四篇】IO流

目录 前言&#xff1a; IO流介绍&#xff1a; IO流的常见方法&#xff1a; 1.字节流类&#xff1a; 2.字符流类&#xff1a; 总结&#xff1a; 前言&#xff1a; IO流就是存入和读取数据的解决方案&#xff0c;并且他是一个知识点很多的章节&#xff0c;因此我们关于IO流…

mysql--InnoDB存储引擎--逻辑结构、内存架构、磁盘架构

MySQL进阶篇 文章目录 1、逻辑结构2、架构2、1 内存架构2、2 磁盘架构 1、逻辑结构 InnoDB 逻辑存储单元主要分为&#xff1a;表空间、段、区、页。层级关系如下图&#xff1a; 2、架构 2、1 内存架构 内存架构由四个部分组成&#xff0c;缓存池&#xff08;Buffer Pool&…

Autosar通信入门系列05-聊聊一帧Can/CanFD报文发送时间?

本文框架 1. 概述2. 一帧CAN报文发送时间计算3. 一帧CanFD报文的传输时间计算3.1 标准CAN与CANFD两者间的区别3.2 CANFD报文传输时间计算 1. 概述 本篇我们一起看下一帧Can报文发送需要多长时间&#xff0c;下述文章里我们会首先计算下Can分别对应的字节数&#xff0c;再根据传…

泛微oa 二次开发指南(ecology)

目录标题 一、环境搭建&#xff08;一&#xff09;先下载安装泛微oa&#xff08;ecology&#xff09;&#xff08;二&#xff09;idea环境搭建二、官方文档三、开发规范&#xff08;里面有入门案例&#xff09;四、三方系统调用oa系统接口五、oa系统所有接口文档六、ecology的一…

EAP设备自动化控制:新能源行业智能化生产的重要工具

随着全球对可再生能源需求的不断增长&#xff0c;新能源行业如锂电池和光伏发电等得到了蓬勃发展。为了满足市场需求&#xff0c;新能源行业需要不断提高生产效率、降低生产成本、改善产品质量。在这个过程中&#xff0c;EAP设备自动化控制成为了新能源行业智能化生产的重要工具…

Redis 源码解析之通用双向链表(adlist)

概述 Redis源码中广泛使用 adlist(A generic doubly linked list)&#xff0c;作为一种通用的双向链表&#xff0c;用于简单的数据集合操作。adlist提供了基本的增删改查能力&#xff0c;并支持用户自定义深拷贝、释放和匹配操作来维护数据集合中的泛化数据 value。 adlist 的…

我的4周年创作纪念日

机缘 今天是2023年8月1日&#xff0c;工作四年了&#xff0c;记录博客也四年了。 2019年&#xff0c;我硕士毕业入职到了这家公司&#xff0c;当时培训的资料有一句话说&#xff1a;网络通信100Mbps是串口通信的是串口通信的10倍&#xff0c;我当时就好奇是怎么算出来的&…

springboot整合mybatis分页(使用pagehelper 分页插件)-- 学习若依系统

学习文档&#xff08;参考若依系统&#xff09; 若依的文档&#xff1a;http://doc.ruoyi.vip/ruoyi-vue/document/htsc.html#%E5%88%86%E9%A1%B5%E5%AE%9E%E7%8E%B0 就不从零搭建springboot项目了&#xff0c;直接在自己的项目基础上引入。 1、引入的依赖 <!-- pagehel…

matlab使用教程(7)—基本画图函数

1.创建绘图 plot 函数具有不同的形式&#xff0c;具体取决于输入参数。 • 如果 y 是向量&#xff0c; plot(y) 会生成 y 元素与 y 元素索引的分段线图。 • 如果有两个向量被指定为参数&#xff0c; plot(x,y) 会生成 y 对 x 的图形。 使用冒号运算符创建从 0 至 2…

ISO-15031/ISO-15765 诊断说明

注&#xff1a;15765诊断可参考15031&#xff0c;两者诊断逻辑相同 1: ISO15031 目录说明 ISO15031-1: 这里边介绍的是一般信息和用例定义&#xff1b; ISO15031-2: 术语、定义、缩写词和首字母缩写词[技术报告] ISO15031-3: 这里边主要介绍了诊断连接器及相关电路&#xff1…

掌握Python的X篇_17_循环语句(while;for var in ;range)

文章目录 1. 为什么需要循环2. while循环3. for...in循环4. range函数 1. 为什么需要循环 循环语句方便我们做重复的事情&#xff0c;比如&#xff1a; for i in range (0,3):print("重要的事情说三遍")运行效果如下&#xff1a; Python中有while循环和for循环两…