正题

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)相关推荐

  1. 吃豆人(luogu 7472/NOI Online 2021 普及组 T2)

    正题 luogu 7472 题目大意 给出一个正方形点阵,让你选择两个点,分别向两个方向移动(必须是45度),每到一个点就得到该点的贡献(不重复得),遇到墙壁反射,问你最大贡献 解题思路 不难发现,从 ...

  2. 【寒假每日一题】洛谷 P7471 [NOI Online 2021 入门组] 切蛋糕

    题目链接:P7471 [NOI Online 2021 入门组] 切蛋糕 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 Alice.Bob 和 Cindy 三个好朋友得到 ...

  3. P7470 [NOI Online 2021 提高组] 岛屿探险

    题目链接:P7470 [NOI Online 2021 提高组] 岛屿探险 以前都没有真正把cdqcdqcdq搞懂过,趁这次比赛花时间学了一下 SolutionSolutionSolution 对于m ...

  4. NOI Online #2 普及组 第二题:荆轲刺秦王

    NOI Online #2 普及组 第二题:荆轲刺秦王 前言 题目 解析 完整代码 前言 做题之前,让我们大吼几声: 你 这 个 " 良 心 " 出 题 人 ! \bold{\so ...

  5. luogu P6476 [NOI Online 2 提高组]涂色游戏color

    题面传送门 考虑一下,其实只要管一个两个倍数点到另一个两个倍数点就好了. 设p1<p2p_1<p_2p1​<p2​ 贪心一下,发现两个倍数点都赋值p2p_2p2​就是最优的. 对于任 ...

  6. luogu P6566 [NOI Online #3 入门组]观星

    题面传送门 直接bfsbfsbfs即可. 代码实现: #include<cstdio> #include<queue> #define max(a,b) ((a)>(b) ...

  7. 数字游戏(NOI Online 2022 普及组)

    题目描述 Kri 喜欢玩数字游戏. 一天,他在草稿纸上写下了 t 对正整数 (x,y),并对于每一对正整数计算出了 z=x×y×gcd(x,y). 可是调皮的 Zay 找到了 Kri 的草稿纸,并把每 ...

  8. 【luogu P7473】重力球

    重力球 题目链接:luogu P7473 题目大意 有一个图中有一些障碍物,边界也是障碍物. 然后又每个询问给出两个小球的位置,你可以改变重力变成左右前后,问你最少要改变多少次重力才能使得两个小球滚到 ...

  9. Cocos Creator 一步一步实现重力球游戏

    「获取源码」 点击上方蓝字关注公众号「游戏开发小白变怪兽」,回复「重力球」获取源码及美术资源. 「游戏玩法」 通过手机陀螺仪,调整手机,让球从上一层的间隔中落到下一层,楼层会不断上涨,如果球碰到上方或 ...

最新文章

  1. 如何设计 QQ、微信、微博、Github 等第三方账号登陆 ?(附表设计)
  2. iOS开发之解决隐藏tabbar后原位置无法响应点击事件的问题
  3. Spring autowire 自动装配简介
  4. Ubuntu安装qwt步骤
  5. OpenCV中的傅里叶的门道
  6. 你必须知道的session与cookie
  7. SpringBoot————快速搭建springboot项目
  8. js获取数组最大值的索引_数组中最大值的返回索引
  9. linux 定时任务 crontab
  10. AndroidStudio_HttpServer类接收到数据以后_给Service发送Message_利用handler实现---Android原生开发工作笔记224
  11. 程序员面试金典——17.1无缓存交换
  12. 转DateTimePicker 控件的使用
  13. Qt QDebug 打印自定义结构体
  14. 迁移学习笔记1:简明手册笔记
  15. java 蓝桥杯 分机号
  16. 电脑开机后鼠标右键点击桌面图标反应很慢,要等上1分钟左右右键内容才能出来怎么办?
  17. java如何获取系统的桌面路径
  18. java aria,ARIA 标签和关系
  19. 攻防世界 Miscellaneous-200
  20. 32位的ane与air sdk升级

热门文章

  1. linux 修改默认脚本,linux环境初始脚本
  2. java 位运算_java学习之运算符与表达式(四)
  3. 调整png的不透明度_TGA与PNG的优劣对比
  4. python字符串截取方法_如何使用python语言中的字符串方法截取字符串
  5. HTML和css重要的知识点,html 和 css 基础知识点(一)(示例代码)
  6. [剑指offer]面试题31:连续子数组的最大和
  7. C++set容器去重法
  8. 多版本opencv 兼容
  9. HDU - 7028 Decomposition 无向完全图构造欧拉回路
  10. AtCoder Regular Contest 100 E - Or Plus Max Sos dp