题意

两个企鹅,一个从地图的右下角走右上角,一个从另一个地图的左下角走到左上角,我们操控左边的企鹅,右边的企鹅与左边企鹅运动规则如下。

  • 左边企鹅向左,右边企鹅向右
  • 左边企鹅向右,右边企鹅向左
  • 左边企鹅向上,右边企鹅向上
  • 左边企鹅向下,右边企鹅向下

    与此同时,如果左右企鹅遇到了障碍,或者遇到了越界情况,那么这一步就作废。

    求最小步数,并且给出字典序最小的方向变化,以及用\('A'\)来体现运动路径。

解题:

说实话真的没见过\(bfs\)还能这样玩的,假设只有一只企鹅那么设状态就\(d[x][y]\),那么两只企鹅就是\(d[x1][y1][x2][y2]\)就好了呀,剩下的就是正常的\(bfs\)过程,对于队列的类型我是用的结构体,看北大大佬的代码使用的元组类型,至于记录路径以及方向,那么就是老套路了,用g数组记录就行。

细节:

  • 要求输出方向字典序最小,那么就是轮询的方向就是下、左、右、上了。
  • 对于切换方向,如果1异或3等于2,2异或3等于1,很巧妙。
  • 处理输入,题目直接给了这样一个输入,两个地图用空格隔开,我可能直接用字符数组一次性保存两个了,处理起来肯定贼麻烦。



    但是可以这样,直接保存两个地图。

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> PII;

const int N = 20;

#define x first
#define y second string a[N], b[N]; int d[N][N][N][N];
int dx[4] = {1, 0, 0, -1}, dy[4] = {0, -1, 1, 0}; struct node {
int x1, y1, x2, y2, i;
}rem[N][N][N][N]; int another(int i) {
if (i == 1 || i == 2) return i ^ 3;
else return i;
} PII move(string g[], int x, int y, int i) {
int xx = x + dx[i], yy = y + dy[i];
if (xx < 0 || xx >= N || yy < 0 || yy >= N || g[xx][yy] == '#') return {x, y};
return {xx, yy};
} void bfs() {
memset(d, -1, sizeof d);
queue<node> q;
q.push({N - 1, N - 1, N - 1, 0});
d[N - 1][N - 1][N - 1][0] = 0; while (q.size()) {
auto t = q.front();
q.pop(); for (int i = 0; i < 4; i++) {
PII leftP = move(a, t.x1, t.y1, i);
PII rightP = move(b, t.x2, t.y2, another(i));
if (d[leftP.x][leftP.y][rightP.x][rightP.y] == -1) {
d[leftP.x][leftP.y][rightP.x][rightP.y] = d[t.x1][t.y1][t.x2][t.y2] + 1;
rem[leftP.x][leftP.y][rightP.x][rightP.y] = {t.x1, t.y1, t.x2, t.y2, i};
q.push({leftP.x, leftP.y, rightP.x, rightP.y});
}
}
}
} int main() {
string a[N], b[N];
for (int i = 0; i < N; i++) cin >> a[i] >> b[i]; bfs(); cout << d[0][N - 1][0][0] << endl; int ex1 = 0, ey1 = N - 1, ex2 = 0, ey2 = 0;
string res = "";
while (true) {
a[ex1][ey1] = b[ex2][ey2] = 'A';
if (ex1 == N - 1 && ey1 == N - 1 && ex2 == N - 1 && ey2 == 0) break;
auto t = rem[ex1][ey1][ex2][ey2];
int x1 = t.x1, y1 = t.y1, x2 = t.x2, y2 = t.y2, i = t.i;
string dir = "DLRU";
res += dir[i];
ex1 = x1, ey1 = y1, ex2 = x2, ey2 = y2;
} reverse(res.begin(), res.end()); cout << res << endl;
for (int i = 0; i < N; i++) {
cout << a[i] << " " << b[i] << endl;
} return 0;
}

牛客多校第二场 I.Penguins的更多相关文章

  1. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

  2. 牛客多校第二场A run(基础DP)

    链接:https://www.nowcoder.com/acm/contest/140/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言2621 ...

  3. run (牛客多校第二场)计数DP

    链接:https://www.nowcoder.com/acm/contest/140/A来源:牛客网 题目描述 White Cloud is exercising in the playground ...

  4. 2019牛客多校第二场H-Second Large Rectangle

    Second Large Rectangle 题目传送门 解题思路 先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位 ...

  5. 2019年牛客多校第二场 H题Second Large Rectangle

    题目链接 传送门 题意 求在\(n\times m\)的\(01\)子矩阵中找出面积第二大的内部全是\(1\)的子矩阵的面积大小. 思路 处理出每个位置往左连续有多少个\(1\),然后对每一列跑单调栈 ...

  6. [2019牛客多校第二场][G. Polygons]

    题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...

  7. 第二大矩阵面积--(stack)牛客多校第二场-- Second Large Rectangle

    题意: 给你一幅图,问你第二大矩形面积是多少. 思路: 直接一行行跑stack求最大矩阵面积的经典算法,不断更新第二大矩形面积,注意第二大矩形可能在第一大矩形里面. #define IOS ios_b ...

  8. 2019 牛客多校第二场 H Second Large Rectangle

    题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...

  9. 2019牛客多校第二场H题(悬线法)

    把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...

  10. 牛客多校第二场H Second Large Rectangle 单调栈or悬线法

    Second Large Rectangle 题意 给出n*m的01矩阵,问由1组成的第二大的矩阵的大小是多少? 分析 单调栈(or 悬线法)入门题 单调栈 预处理出每一个点的最大高度,然后单调栈每一 ...

随机推荐

  1. 2021-7-7 VUE动态样式

    Vue的动态样式实例1 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...

  2. DateTime和DateTimeOffset是同胞兄弟吗?

    小编在日常开发中,用得最多的时间类型就是DateTime,直到一次偶然的邂逅,让小编遇见了DateTimeOffset.当时小编也是一脸迷茫,因为在小编的C#编程字典里就没出现过DateTimeOff ...

  3. 【go语言】2.2.1 数组和切片

    数组和切片是 Go 语言中常用的数据结构,它们都可以存储多个同类型的元素. 数组 数组是具有固定长度的数据类型,它的长度在定义时就已经确定,不能随意改变. 你可以使用以下方式定义一个数组: var a ...

  4. linux-服务操作和运行级别和关机重启

    服务操作: service  network   [] systemctl     [ disable(禁用)  enable(启用)]     network [] 中为操作命令 : 1.statu ...

  5. CSS: 绝对定位fixed

    属性介绍 元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置.元素的位置在屏幕滚动时不会改变.打印时,元素会出现在的每页的固定位置.fi ...

  6. searchsploit用法

    kali里面自带这个工具,用来搜索www.exploit-db.com上面的漏洞库,在由于是提前内置了数据库所以不联网也可以用. 使用之前先更新一下确保是最新的漏洞库 searchsploit --u ...

  7. 《UNIX 传奇:历史与回忆》读后感

    <UNIX 传奇:历史与回忆> 是 bwk(Brian W. Kernighan)2019 年的新作,回忆了 UNIX 在大半个世纪的风雨历程,是一本引人入胜的书籍.通过对 UNIX 操作 ...

  8. koa搭建nodejs项目并注册接口

    使用nodejs注册接口逻辑处理会比较复杂,直接通过express或者koa能够简化开发流程,这里记录用koa来搭建nodejs项目并注册接口,对koa不太熟悉的话可以参考这一篇.让nodejs开启服 ...

  9. LeetCode 周赛上分之旅 #40 结合特征压缩的数位 DP 问题

    ️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...

  10. 《SQL与数据库基础》23. 读写分离

    目录 读写分离 一主一从 准备 配置 双主双从 准备 配置 主库配置 从库配置 从库关联主库 主库相互复制 双主双从读写分离 本文以 MySQL 为例.以 MyCat 数据库中间件为例,通过 MyCa ...