P7473 重力球

P7473 重力球

Solution

考虑 Brute Force:对于每一次询问,通过 BFS 处理出最近的交汇点,输出答案。

很显然,会 TLE \colorbox{navy}{\color{white}{TLE}} TLE

故,考虑 优化

观察发现障碍物数量非常少,故设状态 ( x , y , d ) \mathrm{(x,y,d)} (x,y,d) 表示第 1 1 1 个小球被第 x x x 个障碍物卡住,第 2 2 2 个小球被第 y y y 个小球卡住,在障碍物的 d d d 方向(如图)。此时,发现总共的状态数量不多。

这样我们就可以用着 3 3 3 个数来确定出每个小球的位置。

之后,考虑每一次走一定是走到一个 障碍物四周 的点,所以可以提前预处理,记作 T o i , j , k \mathrm{To_{i,j,k}} Toi,j,k 表示 ( i , j ) (i,j) (i,j) k k k 方向会走到的点。

对于任意两个起点,需要向四周可到达的点连边:

假设当前是 x 1 , y 1 , d \mathrm{x_1,y_1,d} x1,y1,d,方向是 2 2 2,那么运动之后, d = d ⊕ 2 \mathrm{d=d\oplus 2} d=d2(即原来在上面,变成下面;原来在左边,变成右边…… 通过上图观察发现异或 2 2 2 可以解决);点会变为 T o x 1 , y 1 , 2 \mathrm{To_{x_1,y_1,2}} Tox1,y1,2

依此建边即可。


预处理操作结束之后,对于每一个询问:

  1. 直接 BFS 算出终点为哪个点最近(易 T L E \mathrm{TLE} TLE
  2. 正难则反,考虑对于所有可能终点中到这两个点的最短距离,这其实就是一个 多源BFS!注意:使用该方法需建反边!

建议采取第 2 2 2 种操作,当然这样并不需要每一次都进行 BFS,只需提前做 1 1 1 次即可。

由于,每一次询问的时候,不一定是在一个 障碍物四周,所以需要上、下、左、右四个方向,跑到障碍物四周,然后取最小值即可。


Code

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>using namespace std;typedef pair<int, int> PII;
typedef long long LL;const int SIZE = 255;int N, M, Q;
vector<PII> Obstackle;
int Is[SIZE][SIZE], Id[SIZE][SIZE], cnt;
int dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
int To[SIZE][SIZE][4], Dist[SIZE * 5][SIZE * 5][4];
struct P
{int x, y, d;
};
std::vector<P> G[SIZE * 5][SIZE * 5][4];
int Vis[SIZE * 5][SIZE * 5][4];bool check(int x, int y)
{return x >= 1 && y >= 1 && x <= N && y <= N && !Is[x][y];
}void Init()
{for (int i = 1; i <= N; i ++)for (int j = 1; j <= N; j ++)for (int k = 0; k < 4; k ++){int x = i, y = j;while (!Is[x][y])x += dx[k], y += dy[k];To[i][j][k] = Id[x][y];}for (auto i : Obstackle)for (auto j : Obstackle)for (int sd = 0; sd < 4; sd ++)for (int k = 0; k < 4; k ++){int x1 = i.first + dx[k], y1 = i.second + dy[k], x2 = j.first + dx[k], y2 = j.second + dy[k];if (check(x1, y1) && check(x2, y2)){int To1 = To[x1][y1][sd], To2 = To[x2][y2][sd];G[To1][To2][sd ^ 2].push_back({Id[i.first][i.second], Id[j.first][j.second], k});}}
}void BFS()
{memset(Dist, 0x3f, sizeof Dist);queue<P> Q;for (auto c : Obstackle)for (int i = 0; i < 4; i ++){int id = Id[c.first][c.second];int x = c.first + dx[i], y = c.second + dy[i];if (check(x, y))Dist[id][id][i] = 0, Q.push({id, id, i});}while (Q.size()){auto Tmp = Q.front();Q.pop();if (Vis[Tmp.x][Tmp.y][Tmp.d]) continue;Vis[Tmp.x][Tmp.y][Tmp.d] = 1;for (auto c : G[Tmp.x][Tmp.y][Tmp.d])if (Dist[c.x][c.y][c.d] > Dist[Tmp.x][Tmp.y][Tmp.d] + 1){Q.push(c);Dist[c.x][c.y][c.d] = min(Dist[c.x][c.y][c.d], Dist[Tmp.x][Tmp.y][Tmp.d] + 1);}}
}signed main()
{cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);cin >> N >> M >> Q;for (int i = 1; i <= M; i ++){int x, y;cin >> x >> y;Id[x][y] = ++ cnt;Is[x][y] = 1;Obstackle.push_back({x, y});}for (int i = 0; i <= N + 1; i ++)for (int j = 0; j <= N + 1; j ++)if (!i || !j || i > N || j > N){Id[i][j] = ++ cnt;Is[i][j] = 1;Obstackle.push_back({i, j});}Init();BFS();while (Q --){int x1, y1, x2, y2;cin >> x1 >> y1 >> x2 >> y2;int Result = 2e9;for (int i = 0; i < 4; i ++)Result = min(Result, Dist[To[x1][y1][i]][To[x2][y2][i]][i ^ 2] + 1);if (x1 == x2 && y1 == y2) Result = 0;if (Result >= 1e9) Result = -1;cout << Result << endl;}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解密Kubernetes:探索开源容器编排工具的内核

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

系统架构设计师之使用McCabe方法可以计算程序流程图的环形复杂度

系统架构设计师之使用McCabe方法可以计算程序流程图的环形复杂度

AR道具贴纸SDK,创新技术解决方案

增强现实&#xff08;AR&#xff09;技术已经成为企业提升用户体验&#xff0c;增强品牌影响力的重要工具。美摄AR道具贴纸SDK&#xff0c;作为一款领先的AR技术产品&#xff0c;致力于为企业提供一站式的技术解决方案&#xff0c;帮助企业轻松实现AR应用的快速开发和部署。 一…

Git(SourceTree)变基操作使用

文章目录 一、变基的使用场景二、Source Tree上的变基操作1. 准备两个分支dev1和master2. 切换到dev1中&#xff0c;并选中master中提交的代码3. 鼠标右键&#xff0c;选择变基&#xff0c;弹出对话框选择确定。 变基就是rebase操作 一、变基的使用场景 假设分支a和分支b 在分…

vscode 保存 “index.tsx“失败: 权限不足。选择 “以超级用户身份重试“ 以超级用户身份重试。

vscode 保存 "index.tsx"失败: 权限不足。选择 “以超级用户身份重试” 以超级用户身份重试。 操作&#xff1a;mac在文件夹中创建文件&#xff0c;sudo 创建umiJs项目 解决&#xff1a;修改文件夹权限 右键文件夹

【C#】LIMS实验室信息管理系统源码

一、系统概述 LIMS(Laboratory Information Management System)即实验室信息管理系统,是通过对样品检验流程、分析数据及报告、实验室资源和客户信息等要素的综合管理,按照标准化实验室管理规范,建立符合实验室业务流程的质量体系,实现实验室信息化管理。是实验室提高分析水平…

laravel+vue2 element 一套项目级医院手术麻醉信息系统源码

手术麻醉临床信息系统源码&#xff0c;PHPmysqllaravelvue2 手术麻醉临床信息系统&#xff0c;采用计算机和通信技术&#xff0c;实现监护仪、麻醉机、输液泵等设备输出数据的自动采集&#xff0c;采集的数据能够如实准确地反映患者生命体征参数的变化&#xff0c;并实现信息高…

栈、队列、矩阵的总结

栈的应用 括号匹配 表达式求值&#xff08;中缀&#xff0c;后缀&#xff09; 中缀转后缀&#xff08;机算&#xff09; 中缀机算 后缀机算 总结 特殊矩阵 对称矩阵的压缩存储 三角矩阵 三对角矩阵 稀疏矩阵的压缩存储

[javaweb]——spring框架之控制反转(IOC)与依赖注入(DI)

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、概念介绍 二、示例演示 2.1 代码高内聚问题 2.2 三层架构 2.3 分层解耦 2.4 分层解耦的实现 &#x1f4d5;总结 一、概念介绍 控制反转&#xff1a;简称IOC&#xff0c;对象的创建控制权由程序自身转…

DevChat:VSCode中的AI黑马

前言 编程对于很多人来说&#xff0c;可能是一件复杂且耗时的事情。在结合当下各类AI产品层出不穷的情况下&#xff0c;我是有在认真的去拥抱AI来结合我们的工作&#xff0c;帮助我们的工作提升效率&#xff0c;尝试过我们的官方G P T&#xff0c;以及各类国产AI产品&#xff…

Python 框架学习 Django篇 (六) ORM关联

像是上一章我们很少会通过页面点击去添加和绑定关系表&#xff0c;更多的时候都是通过django的语法实现&#xff0c;接下来我们做一个案例 django rom是怎么操作外键关系的 创建mode模型表 Django_demo/mgr/models.py # 国家表 class Country(models.Model):name models.Cha…

ubuntu安装nps客户端

Ubuntu安装nps客户端 1.什么是nps内网穿透&#xff1f;2.设备情况3.下载客户端3.链接服务端3.1、无配置文件模式3.2、注册到系统服务(启动启动、监控进程) 1.什么是nps内网穿透&#xff1f; nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发…