P7473 [NOI Online 2021 入门组] 重力球
P7473 [NOI Online 2021 入门组] 重力球
题意
给你一个正方形平面,某些位置有障碍,对于平面上两个球,每次你可以改变重力方向使两个球下落到最底端,求使两个球位置重合的最小改变重力次数。障碍固定,多次询问两个球的位置。
思路
考虑最暴力的想法,总共有 \(n^4\) 种状态,即两个球的坐标。
考虑优化状态数,发现只有障碍物(边界)旁边(四联通)的位置才有用。实际最大位置数为 \(250\times 4+250\times 4=2000\) 左右。那么实际状态数最大为 \(2000\times 2000=4000000\) 左右。
我们把这些状态看做点,每个点只能有四条出边,那么边数和点数同阶。这样我们就有了另外一个暴力的想法:对于每个初始局面,暴力 BFS。
因为有多组询问考虑优化。实际上最终重合的状态有 \(2000\) 个,我们反向建边,然后从这些点开始 BFS 出到所有状态的最小代价。每次查询的时候枚举第一次改变重力的方向即可。(注意判重合)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=x*10+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=255,maxm=2010;
int n,m,Q,tot,a[maxn][maxn],t[maxn][maxn][4];
unsigned dis[maxm][maxm];
vector<int> to[maxm][4];
inline void addedge(int a,int b,int c){to[a][c].push_back(b);}
inline void work(){
n=read(),m=read(),Q=read();
while(m--) a[read()][read()]=-1;
for(int i=1;i<=n;a[0][i]=a[i][0]=a[n+1][i]=a[i][n+1]=-1,i++) for(int j=1;j<=n;j++)
if(!a[i][j] and (a[i-1][j]==-1 or a[i+1][j]==-1 or a[i][j-1]==-1 or a[i][j+1]==-1))
a[i][j]=++tot;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) t[i][j][0]=a[i][j-1]==-1?a[i][j]:t[i][j-1][0],t[i][j][1]=a[i-1][j]==-1?a[i][j]:t[i-1][j][1];
for(int i=n;i;i--) for(int j=n;j;j--) t[i][j][2]=a[i][j+1]==-1?a[i][j]:t[i][j+1][2],t[i][j][3]=a[i+1][j]==-1?a[i][j]:t[i+1][j][3];
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(a[i][j]>0) for(int k=0;k<4;k++) addedge(t[i][j][k],a[i][j],k);
static pair<int,int> q[maxm*maxm];
int hd=0,tl=0;
memset(dis,-1,sizeof dis);
for(int i=1;i<=tot;i++) q[++tl]=make_pair(i,i),dis[i][i]=1;
while(hd<tl){
pair<int,int> x=q[++hd];
for(int i=0;i<4;i++) for(auto u:to[x.first][i]) for(auto v:to[x.second][i]) if(dis[u][v]==-1) dis[u][v]=dis[x.first][x.second]+1,q[++tl]=make_pair(u,v);
}
while(Q--){
int x1=read(),y1=read(),x2=read(),y2=read();
if(x1==x2 and y1==y2) puts("0");
else printf("%d\n",min({dis[t[x1][y1][0]][t[x2][y2][0]],dis[t[x1][y1][1]][t[x2][y2][1]],dis[t[x1][y1][2]][t[x2][y2][2]],dis[t[x1][y1][3]][t[x2][y2][3]]}));
}
}
}
signed main(){
star::work();
return 0;
}
P7473 [NOI Online 2021 入门组] 重力球的更多相关文章
- [题解] [NOI Online 2021 入门组 T3] 重力球
题目大意 在一个 \(n\times n\) 的矩形中,题目会给出 \(m\) 个障碍物.有两个小球,你可以选定四个方向(上下左右)的其中一个,小球会朝着这四个方向一直滚动,直到遇到障碍物或是矩形的边 ...
- NOI Online 2021 入门组 T1
Description 题目描述 Alice.Bob 和 Cindy 三个好朋友得到了一个圆形蛋糕,他们打算分享这个蛋糕. 三个人的需求量分别为 \(a, b, c\),现在请你帮他们切蛋糕,规则如下 ...
- P6474 [NOI Online #2 入门组] 荆轲刺秦王
P6474 [NOI Online #2 入门组] 荆轲刺秦王 bfs+差分+卡常 本来我其实是场内选手,但是因为记错提交时间,晚了半小时才交,交不上了,就自动降级为了场外选手 题面复杂,不简述了 首 ...
- [NOI Online 2021 提高组] 积木小赛
思路不说了. 想起来自己打比赛的时候,没睡好.随便写了个\(HASH\),模数开小一半分都没有. 然后学了\(SAM\),发现这个判重不就是个水题. \(SAM\)是字串tire的集合体. 随便\(d ...
- 洛谷 P6189 - [NOI Online #1 入门组]跑步(根号分治+背包)
题面传送门 题意: 求有多少个数列 \(x\) 满足: \(\sum x_i=n\) \(x_i\geq x_{i+1}\) 答案对 \(p\) 取模. ...你确定这叫"入门"组 ...
- [NOI 2020 Online] 入门组T1 文具采购(洛谷 P6188)题解
原题传送门 题目部分:(来自于考试题面,经整理) [题目描述] 小明的班上共有 n 元班费,同学们准备使用班费集体购买 3 种物品: 1.圆规,每个 7 元. 2.笔,每支 4 元. 3.笔记本,每本 ...
- NOI Online #1 入门组 魔法
全网都是矩阵快速幂,我只会倍增DP 其实这题与 AcWing 345. 牛站 还是比较像的,那题可以矩阵快速幂 / 倍增,这题也行. 先 \(Floyd\) 预处理两点之间不用魔法最短距离 \(d_{ ...
- CCF NOI Online 2021 提高组 赛后心得
T1 做个,不会,拿到 20 pts 跑路. 注意后面有个 K = 1 的部分分,这个可以递推求 b 的个数,然后直接乘上 a0 . 官方正解讲得极其详细,我还是第一次见到可以 O(K2) 做 1~n ...
- CCF NOI Online 2021 提高组 T3 岛屿探险(CDQ 分治,Trie 树)
题面 凇睦是一个喜欢探险的女孩子,这天她到一片海域上来探险了. 在这片海域上一共有 n 座岛屿排成一排,标号为 1, 2, 3, . . . , n.每座岛屿有两个权值,分别为劳累度 ai 和有趣度 ...
随机推荐
- 【NX二次开发】Block UI 指定轴
属性说明 属性 类型 描述 常规 BlockID String 控件ID Enable Logical 是否可操作 Group ...
- Netty 框架学习 —— 基于 Netty 的 HTTP/HTTPS 应用程序
通过 SSL/TLS 保护应用程序 SSL 和 TLS 安全协议层叠在其他协议之上,用以实现数据安全.为了支持 SSL/TLS,Java 提供了 javax.net.ssl 包,它的 SSLConte ...
- 进程与线程 .Net Core系列-多线程
进程与线程 进程: 狭义定义:进程是正在运行的程序的实例 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动.它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分 ...
- moment常用方法
1.subtract方法,时间加减处理 console.log(moment().format("YYYY-MM-DD HH:mm:ss")); //当前时间 console.lo ...
- DL基础补全计划(一)---线性回归及示例(Pytorch,平方损失)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 『心善渊』Selenium3.0基础 — 15、Selenium对多窗口的操作
目录 1.多标签/多窗口之间的切换 2.句柄练习 1.多标签/多窗口之间的切换 (1)多标签/多窗口场景: 在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要切换到新打开的窗口上进行操作,如 ...
- Redis 雪崩、穿透、击穿、并发、缓存讲解以及解决方案
1.缓存雪崩 数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机. 比如一个雪崩的简单过程 1.redis集群大面积故障 2.缓存 ...
- JS中的单例模式及单例模式原型类的实现
单例模式 单例模式的定义: 保证一个类只有一个实例,并提供一个访问它的全局访问点 通过一个简单的例子来了解单例模式的作用: class Div { constructor() { return doc ...
- powerpoint2013去掉图片背景,转存png
1.打开powerpoint,点击菜单栏的[插入],如图: 2.点击『图像』,如图: 3.上传图片,如图: 4.上传的图片不是png的,现在需要去掉白色背景,保存成png,选中图片,点击菜单栏的『格式 ...
- Linux:CentOS7防火墙 开放端口配置
查看已开放的端口 firewall-cmd --list-ports 开放端口(开放后需要要重启防火墙才生效) firewall-cmd --zone=public --add-port=3338/t ...