【LOJ3099】[SNOI2019]积木(搜索)
lca 学长出的我省省选的神仙题目 省强我菜系列
题目
分析
我可能说不清楚,对着代码理解吧 …… 感觉这题的主要难点是:不要想他具体是怎么操作的,只要知道他一定存在一种操作方式能够实现就行了。
首先要注意到一个很重要的性质:对于当前空格所在的点,除非这个点在目标中就是空格,否则一定可以通过一步操作使这个点变得和目标中一样(下称「变得和目标中一样」为「归位」)。例如,如果这个点最终是朝上的(意思是这个点是一个上下方向的块的下半部分,朝下、朝左、朝右同理),那么无论它上面是一个朝上还是朝左还是朝右(显然不可能朝下)的块,都可以通过移动它上面的块来使这个点变得朝上。这样只需要不断地通过这种操作使空格所在的块归位,就可以让空格到达目标中的空格的位置。
但是,这个过程中不能保证访问到了所有格子,所以有些未归位的格子可能没有被发现。因此在把空格归位后要去主动寻找未归位的格子。具体方法是用 dfs 主动寻找未归位的格子。虽然这样会让已经归位的格子变成未归位,但是回溯的时候挪回去就行了。每找到一个未归位的格子就像上一段描述的一样使它归位,直到空格又回到 dfs 找到的这个地方。如此把所有格子都 dfs 一遍,就能让所有格子归位。
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
namespace zyt
{
const int N = 2e3 + 10, M = 8e6 + 10, CH = 128;
const int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
const char opt[] = {'R', 'L', 'D', 'U'}, ch[] = {'<', '>', 'n', 'u'};
char a[N][N], b[N][N], ans[M];
bool vis[N][N];
int cntans, n, m, dir[CH];
void move(const int d, int &x, int &y)
{
ans[cntans++] = opt[d];
int x1 = x + dx[d], y1 = y + dy[d];
if (x1 < 0 || x1 >= n || y1 < 0 || y1 >= m)
fprintf(stderr, "gg");
int x2 = x1 + dx[dir[a[x1][y1]]], y2 = y1 + dy[dir[a[x1][y1]]];
a[x][y] = ch[d], a[x1][y1] = ch[d ^ 1], a[x2][y2] = 'o';
x = x2, y = y2;
}
void go(int &x, int &y, const int x1, const int y1)
{
while (x != x1 || y != y1)
move(dir[b[x][y]], x, y);
}
void dfs(int x, int y)
{
vis[x][y] = true;
for (int d = 0; d < 4; d++)
{
int x1 = x + dx[d], y1 = y + dy[d];
if (x1 < 0 || x1 >= n || y1 < 0 || y1 >= m || vis[x1][y1])
continue;
if (a[x1][y1] != b[x1][y1])
{
int x0 = x, y0 = y;
move(d, x, y);
go(x, y, x0, y0);
}
vis[x1][y1] = true;
int dd = dir[a[x1][y1]];
move(d, x, y);
dfs(x, y);
move(dd ^ 1, x, y);
}
}
int work()
{
dir['<'] = 0, dir['>'] = 1, dir['n'] = 2, dir['u'] = 3;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
scanf("%s", a[i]);
for (int i = 0; i < n; i++)
scanf("%s", b[i]);
int x, y, x1, y1;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (a[i][j] == 'o')
x = i, y = j;
if (b[i][j] == 'o')
x1 = i, y1 = j;
}
go(x, y, x1, y1);
dfs(x, y);
printf("%s", ans);
return 0;
}
}
int main()
{
return zyt::work();
}
【LOJ3099】[SNOI2019]积木(搜索)的更多相关文章
- NOIP 模拟 玩积木 - 迭代加深搜索 / bfs+hash+玄学剪枝
题目大意: 有一堆积木,0号节点每次可以和其上方,下方,左上,右下的其中一个交换,问至少需要多少次达到目标状态,若步数超过20,输出too difficult 目标状态: 0 1 1 2 2 2 3 ...
- 「SNOI2019」积木
传送门 Description 有一块\(n\)行\(m\)列的网格板, \(n,m\)都是奇数.网格上平铺着一些\(1*2\)的积木.积木可以旋转,不能重叠.网格板上只有一格的空位. 你可以做两种操 ...
- 洛谷P2409 Y的积木
P2409 Y的积木 77通过 491提交 题目提供者zhouyonglong 标签云端评测 难度普及+/提高 提交 讨论 题解 最新讨论 这组数据几乎可以卡掉所有程- 第一个题解有点问题 求教大 ...
- 深度优先搜索(DFS)递归形式改为非递归形式
DFS将递归改为非递归这个方法的需求来自于一道三维积木组合的题目,还在苦苦调试中,暂且不提. 普通的认识对于递归向非递归的转化无非是使用栈,但是结合到深度搜索如何将栈很好利用,如何很好保存现场,都不是 ...
- XJOI1657&Codevs1255搭积木【树状动规】
搭积木 一种积木搭建方式,高为H的积木,最底层有M个积木,每一层的积木数是他的低一层的积木数+1或-1.总共有N个积木.(且每行积木数不超过10)比如上图N=13 H=6 M=2. 输入格式: 第一行 ...
- C# 全文搜索Lucene
全文出自:https://blog.csdn.net/huangwenhua5000/article/details/9341751 1 lucene简介1.1 什么是luceneLucene是一个全 ...
- code1225 搭积木
题目分析:将当前层定义为第h层,共用了n块积木,本层积木数为m,f(h,n,m) 那么可以扩展数两种状态:f(h-1,n-m,m-1),f(h-1,n-m,m+1) 直接搜索可能的数据达到h^m,超时 ...
- codevs 1255 搭积木 x
1255 搭积木 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 一种积木搭建方式,高为H的积木,最底层有M个积木,每一层的积木 ...
- 基于层级表达的高效网络搜索方法 | ICLR 2018
论文基于层级表达提出高效的进化算法来进行神经网络结构搜索,通过层层堆叠来构建强大的卷积结构.论文的搜索方法简单,从实验结果看来,达到很不错的准确率,值得学习 来源:[晓飞的算法工程笔记] 公众号 ...
随机推荐
- java内部类的本质
连接与通信,作为桥接中间件存在. 内部类和主体类可以无障碍通信: 1.通过继承连接实现: 2.通过接口连接通信: 形式: 1.命名空间: 2.运行上下文: 其它: 信息隐藏是次要功能. 内部类 Jav ...
- 函数式编程—函数的关系—is-a、has-a、use-a
is-a:函数的实现与函数类型的关系: has-a:匿名(闭包)函数的创建者与匿名函数的关系:匿名函数与环境和上下文(函数)的关系: use-a:高阶函数与参量函数的关系: 函数式编程的基本功之一就是 ...
- Docker部署ngnix静态网站
Hello World 首先获取ngnix镜像(默认的是最新版. docker pull nginx 先来编写一个最简单的Dockerfile,一个Dockerfile修改该Nginx镜像的首页 Do ...
- python语言(四)关键字参数、内置函数、导入第三方模块、OS模块、时间模块
一.可变参数 定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以).此时,可用包裹(packing)位置参数(*args),或者包裹关键字参数(**kwargs),来进行参数传递,会 ...
- nightwatch 基于Webdriver的端到端自动化测试框架
nightwatch 是使用nodejs编写的,基于Webdriver api 的端到端自动化测试框架 包含以下特性 清晰的语法,基于js 以及css 还有xpath 的选择器 内置测试runner, ...
- dubbo简单示例
dubbo简单示例 2019-09-06 1 Zookeeper注册中心的搭建(windows单机) 下载zookeeper压缩包并解压到 D:\zookeeper\apache-zookeeper- ...
- 微服务看门神-Zuul
Zuul网关和基本应用场景 构建微服务时,常见的问题是为系统的客户端应用程序提供唯一的网关. 事实上,您的服务被拆分为小型微服务应用程序,这些应用程序应该对用户不可见,否则可能会导致大量的开发/维护工 ...
- 解决vue项目路由出现message: "Navigating to current location (XXX) is not allowed"的问题(点击多次跳转)
如果网页跳转用的方法传参去跳转: (点击多次链接会出现错误) <a class="" href="javascript:void(0);" @click= ...
- ubuntu18 任务栏调到底部
$ gsettings set org.gnome.shell.extensions.dash-to-dock dock-position BOTTOM 原因如下: https://askubuntu ...
- xshell如何导入.xsh 文件
xshell 不能导入 xsh 文件 导入功能 只能导入 *.xts, *.csv, *.tsv 文件,不能直接导入 .xsh 其实 xsh文件不需要导入,直接拷贝进去就可以了(.xsh 本来就是 x ...