gym102798 2020CCPC威海B Labyrinth

9 篇文章 0 订阅
3 篇文章 0 订阅
题目:

给定一个 n × m n \times m n×m的网格图,图上有 k k k个黑洞,从一个点出发一步可以往上下左右走一格,不能走出网格图且不能走进黑洞,给定 q q q次询问,每次给定两个点 s , t s,t s,t,问从 s s s t t t的最少步数,或输出-1表示不能到达。
( 1 ≤ n m ≤ 200000 , 0 ≤ k ≤ 42 , 1 ≤ q ≤ 100000 ) (1 \le nm \le 200000,0 \le k \le 42,1 \le q \le 100000) (1nm200000,0k42,1q100000)

题解:

发现黑洞的个数很少,肯定从这里入手。
可以发现如果以 s , t s,t s,t作为对角顶点的矩形内如果没有黑洞,那么答案为 ∣ s x − t x ∣ + ∣ s y − t y ∣ |s_x-t_x|+|s_y-t_y| sxtx+syty。如果矩形内有黑洞,那么要么不可达,如果可达的话,一定存在一条经过黑洞边上的非黑洞点的路径。所以用 b f s bfs bfs预处理出所有黑洞边上的非黑洞点到各个点的最短距离,然后每次遍历所有这些点,计算并更新答案。

复杂度: O ( k n m + k q ) O(knm+kq) O(knm+kq)
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<sstream>
#include<ctime>
//#include<chrono>
//#include<random>
//#include<unordered_map>
using namespace std;

#define ll long long
#define ls o<<1
#define rs o<<1|1
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
const double pi=acos(-1.0);
const double eps=1e-6;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn=2e5+5;
ll read(){
	ll x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
queue<pair<pii,int> >q;
int n,m,k,Q;
vector<int>g[maxn],vis[maxn];
pii hole[55];
struct hole_side{
	int x,y;
	vector<int>dis[maxn];
}hs[205];
int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};
map<pii,int>buf;
int ck(int x,int y){
	return 1<=x&&x<=n&&1<=y&&y<=m;
}
void bfs(hole_side &st){
	while(!q.empty())q.pop();
	q.push(mp(mp(st.x,st.y),0));
	for(int i=1;i<=n;i++){
		vis[i].resize(m+1);
		fill(all(vis[i]),0);
		st.dis[i].resize(m+1);
		fill(all(st.dis[i]),-1);
	}
	vis[st.x][st.y]=1;
	while(!q.empty()){
		pair<pii,int> u=q.front();q.pop();
		st.dis[u.fi.fi][u.fi.se]=u.se;
		for(int i=0;i<4;i++){
			int nx=u.fi.fi+dir[i][0],ny=u.fi.se+dir[i][1];
			if(!ck(nx,ny))continue;
			if(vis[nx][ny])continue;
			if(g[nx][ny])continue;
			vis[nx][ny]=1;
			q.push(mp(mp(nx,ny),u.se+1));
		}
	}
}
int main(void){
	// freopen("in.txt","r",stdin);
	scanf("%d%d%d%d",&n,&m,&k,&Q);
	for(int i=1;i<=n;i++){
		g[i].resize(m+1);
		fill(all(g[i]),0);
	}
	int tot=0;
	for(int i=1;i<=k;i++){
		scanf("%d%d",&hole[i].fi,&hole[i].se);
		g[hole[i].fi][hole[i].se]=1;
	}	
	for(int i=1;i<=k;i++){
		for(int j=0;j<4;j++){
			int nx=hole[i].fi+dir[j][0],ny=hole[i].se+dir[j][1];
			if(!ck(nx,ny)||buf[mp(nx,ny)]||g[nx][ny])continue;
			++tot;
			hs[tot].x=nx;hs[tot].y=ny;
			buf[mp(nx,ny)]=1;
		}
	}
	for(int i=1;i<=tot;i++){
		bfs(hs[i]);
	}
	pii s,t;
	while(Q--){
		scanf("%d%d%d%d",&s.fi,&s.se,&t.fi,&t.se);
		if(g[s.fi][s.se]||g[t.fi][t.se]){
			puts("-1");
			continue;
		}
		int lx=min(s.fi,t.fi),rx=max(s.fi,t.fi);
		int ly=min(s.se,t.se),ry=max(s.se,t.se);
		int flag=0;
		for(int i=1;i<=tot;i++){
			if(lx<=hs[i].x&&hs[i].x<=rx&&ly<=hs[i].y&&hs[i].y<=ry){
				flag=1;
				break;
			}
		}
		if(!flag){
			printf("%d\n",rx-lx+ry-ly);
		}
		else{
			int ans=INF;
			for(int i=1;i<=tot;i++){
				if(hs[i].dis[s.fi][s.se]!=-1&&hs[i].dis[t.fi][t.se]!=-1){
					ans=min(ans,hs[i].dis[s.fi][s.se]+hs[i].dis[t.fi][t.se]);
				}
			}
			if(ans==INF)puts("-1");
			else{
				printf("%d\n",ans);
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自2020年以来,自动驾驶汽车(Autonomous Vehicle)在这一领域取得了显著进展。 自动驾驶汽车通过使用先进的传感技术,如雷达、激光雷达和摄像头,以及深度学习和人工智能算法,实现了车辆的自主驾驶。它们能够感知周围环境,了解道路状况,并做出相应的决策和行驶动作,从而实现无需人类操控的车辆行驶。 自动驾驶汽车在2020年迅速崭露头角。它们的技术日益成熟,不断的实验和测试表明其在安全性和性能方面已经取得了显著的突破。虽然仍然存在一些挑战,比如在复杂城市环境中导航和处理紧急情况,但这些问题正经过不断的研究和改进来得以解决。 在未来,自动驾驶汽车有望在各个领域发挥重要作用。首先,它们将可以提高道路交通的安全性。由于自动驾驶车辆不受人类司机的疲劳、分心和驾驶误差的限制,它们的驾驶能力更为稳定和准确。其次,自动驾驶汽车还能够提高交通效率。通过与其他车辆实时通信和协同,它们可以避免交通堵塞和减少事故发生,从而减少交通拥堵和行车时间成本。 此外,自动驾驶汽车也将为交通出行带来便利和舒适性。乘客可以更轻松地进行其他活动,如工作、休息或娱乐,而不必担心驾驶问题。老年人和残障人士也将能够自由独立地出行,提高他们的生活质量。 综上所述,作为2020年的重要趋势,自动驾驶汽车具有广阔的应用前景。通过不断的创新和发展,它们将在道路交通安全、交通效率和出行体验方面取得进一步的提升。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值