【bfs】重力球(luogu 7473/NOI Online 2021 普及组 T3)
正题
luogu 7473
题目大意
给出一个正方形区域,中间有一些障碍
现在有两个球,每次操作可以使两个球同时向一个方向移动,直到遇到障碍或边界
现在问你让两个球到同一个位置最少要多少步
解题思路
对于每次操作,球只有可能停在障碍四周的格子内(边界视为障碍),把这些格子记录下来
然后暴力枚举它们之间的连边,这里倒着连边从最终状态转移到初始状态
对于每个这样的点x,建立状态(x,x),两个值分别为当前状态两个点的位置,那么bfs即可
代码
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 260
using namespace std;
int n, m, q, x, y, w, g, xx, yy, tot, p[N][N], v[N][N], f[N*20][N*20], head[N*20][4], to[N][N][4];
struct rec
{int to, next;
}a[N*20*4];
struct node
{int x, y;
};
queue<node>d;
bool check(int x, int y)
{return p[x + 1][y] || p[x - 1][y] || p[x][y + 1] || p[x][y - 1];
}
void add(int x, int y, int z)
{a[++tot].to = y;a[tot].next = head[x][z];head[x][z] = tot;
}
int main()
{scanf("%d%d%d", &n, &m, &q);for (int i = 1; i <= m; ++i){scanf("%d%d", &x, &y);p[x][y] = 1;}for (int i = 1; i <= n; ++i)p[i][0] = p[i][n + 1] = p[0][i] = p[n + 1][i] = 1;for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)if (!p[i][j] && check(i, j))v[i][j] = ++w;//记下特殊点for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j){to[i][j][0] = p[i][j - 1] ? v[i][j] : to[i][j - 1][0];//查询往各个方向走会到哪个点to[i][j][1] = p[i - 1][j] ? v[i][j] : to[i - 1][j][1];}for (int i = n; i > 0; --i)for (int j = n; j > 0; --j){to[i][j][2] = p[i][j + 1] ? v[i][j] : to[i][j + 1][2];to[i][j][3] = p[i + 1][j] ? v[i][j] : to[i + 1][j][3];}for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)if (v[i][j])for (int k = 0; k < 4; ++k)add(to[i][j][k], v[i][j], k);//连反边memset(f, 127/3, sizeof(f));for (int i = 1; i <= w; ++i){d.push((node){i, i});//最终状态f[i][i] = 0;}while(!d.empty()){node h = d.front();d.pop();for (int k = 0; k < 4; ++k)//bfsfor (int i = head[h.x][k]; i; i = a[i].next)for (int j = head[h.y][k]; j; j = a[j].next)if (f[a[i].to][a[j].to] > 1e8){f[a[i].to][a[j].to] = f[h.x][h.y] + 1;d.push((node){a[i].to, a[j].to});}}while(q--){scanf("%d%d%d%d", &x, &y, &xx, &yy);g = x == xx && y == yy ? 0 : 1e8;for (int k = 0; k < 4; ++k)g = min(g, f[to[x][y][k]][to[xx][yy][k]] + 1);//往其中一个方向走,然后就可以直接使用bfs得出的结果if (g < 1e8) printf("%d\n", g);else puts("-1");}return 0;
}
【bfs】重力球(luogu 7473/NOI Online 2021 普及组 T3)相关推荐
- 吃豆人(luogu 7472/NOI Online 2021 普及组 T2)
正题 luogu 7472 题目大意 给出一个正方形点阵,让你选择两个点,分别向两个方向移动(必须是45度),每到一个点就得到该点的贡献(不重复得),遇到墙壁反射,问你最大贡献 解题思路 不难发现,从 ...
- 【寒假每日一题】洛谷 P7471 [NOI Online 2021 入门组] 切蛋糕
题目链接:P7471 [NOI Online 2021 入门组] 切蛋糕 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 Alice.Bob 和 Cindy 三个好朋友得到 ...
- P7470 [NOI Online 2021 提高组] 岛屿探险
题目链接:P7470 [NOI Online 2021 提高组] 岛屿探险 以前都没有真正把cdqcdqcdq搞懂过,趁这次比赛花时间学了一下 SolutionSolutionSolution 对于m ...
- NOI Online #2 普及组 第二题:荆轲刺秦王
NOI Online #2 普及组 第二题:荆轲刺秦王 前言 题目 解析 完整代码 前言 做题之前,让我们大吼几声: 你 这 个 " 良 心 " 出 题 人 ! \bold{\so ...
- luogu P6476 [NOI Online 2 提高组]涂色游戏color
题面传送门 考虑一下,其实只要管一个两个倍数点到另一个两个倍数点就好了. 设p1<p2p_1<p_2p1<p2 贪心一下,发现两个倍数点都赋值p2p_2p2就是最优的. 对于任 ...
- luogu P6566 [NOI Online #3 入门组]观星
题面传送门 直接bfsbfsbfs即可. 代码实现: #include<cstdio> #include<queue> #define max(a,b) ((a)>(b) ...
- 数字游戏(NOI Online 2022 普及组)
题目描述 Kri 喜欢玩数字游戏. 一天,他在草稿纸上写下了 t 对正整数 (x,y),并对于每一对正整数计算出了 z=x×y×gcd(x,y). 可是调皮的 Zay 找到了 Kri 的草稿纸,并把每 ...
- 【luogu P7473】重力球
重力球 题目链接:luogu P7473 题目大意 有一个图中有一些障碍物,边界也是障碍物. 然后又每个询问给出两个小球的位置,你可以改变重力变成左右前后,问你最少要改变多少次重力才能使得两个小球滚到 ...
- Cocos Creator 一步一步实现重力球游戏
「获取源码」 点击上方蓝字关注公众号「游戏开发小白变怪兽」,回复「重力球」获取源码及美术资源. 「游戏玩法」 通过手机陀螺仪,调整手机,让球从上一层的间隔中落到下一层,楼层会不断上涨,如果球碰到上方或 ...
最新文章
- 如何设计 QQ、微信、微博、Github 等第三方账号登陆 ?(附表设计)
- iOS开发之解决隐藏tabbar后原位置无法响应点击事件的问题
- Spring autowire 自动装配简介
- Ubuntu安装qwt步骤
- OpenCV中的傅里叶的门道
- 你必须知道的session与cookie
- SpringBoot————快速搭建springboot项目
- js获取数组最大值的索引_数组中最大值的返回索引
- linux 定时任务 crontab
- AndroidStudio_HttpServer类接收到数据以后_给Service发送Message_利用handler实现---Android原生开发工作笔记224
- 程序员面试金典——17.1无缓存交换
- 转DateTimePicker 控件的使用
- Qt QDebug 打印自定义结构体
- 迁移学习笔记1:简明手册笔记
- java 蓝桥杯 分机号
- 电脑开机后鼠标右键点击桌面图标反应很慢,要等上1分钟左右右键内容才能出来怎么办?
- java如何获取系统的桌面路径
- java aria,ARIA 标签和关系
- 攻防世界 Miscellaneous-200
- 32位的ane与air sdk升级
热门文章
- linux 修改默认脚本,linux环境初始脚本
- java 位运算_java学习之运算符与表达式(四)
- 调整png的不透明度_TGA与PNG的优劣对比
- python字符串截取方法_如何使用python语言中的字符串方法截取字符串
- HTML和css重要的知识点,html 和 css 基础知识点(一)(示例代码)
- [剑指offer]面试题31:连续子数组的最大和
- C++set容器去重法
- 多版本opencv 兼容
- HDU - 7028 Decomposition 无向完全图构造欧拉回路
- AtCoder Regular Contest 100 E - Or Plus Max Sos dp