【0】题解:AT_abc413_g [ABC413G] Big Banned Grid

有史以来最简单的 G 题。

题意:给你一个 \(H\times M\) 的地图,然后给你 \(K\) 个障碍物,问左上是否能走到右下。

首先直接走会超时,因为地图大小是 \(H\times M\leq 10^{10}\)。我们考虑转化这个问题,判断是否有一条墙壁完整挡住了地图。这时我们就需要分一下类:

  • 左侧墙壁走到右边或上面,把地图分开。
  • 底下墙壁走到右边或上面,把地图分开。

然后我们考虑如何找这样的墙壁。可以考虑用 set 记录,枚举一下墙壁的起点,然后暴力搜。注意这里要用八连通的搜法,原因可以看样例的墙壁。并且,每搜一个点,就要删掉 set 内的记录,表示已经存在了。当墙壁闭合,也就是框住了起点,问题也就有答案了。

具体看代码:

#include<bits/stdc++.h>
using namespace std;
int h,m,k;
int dx[]={0,1,0,-1,1,1,-1,-1},
	dy[]={1,0,-1,0,-1,1,-1,1};
set<pair<int,int>>Node;
void dfs(int x,int y){
	Node.erase({x,y}); // use
	if(x==h||y==1){
		// webbed.
		cout<<"No\n";
		exit(0);
	}
	for(int i=0;i<8;i++){
		int nx=x+dx[i],
			ny=y+dy[i];
		if(nx<1||ny<1||nx>h||ny>m)
			continue;
		if(!Node.count({nx,ny}))
			continue;
		dfs(nx,ny);
	}
}
signed main(){
	cin>>h>>m>>k;
	for(int i=1;i<=k;i++){
		int x,y;
		cin>>x>>y;
		Node.insert({x,y});
	}
	for(int i=1;i<=m;i++)
		if(Node.count({1,i}))dfs(1,i);
	for(int i=1;i<=h;i++)
		if(Node.count({i,m}))dfs(i,m);
	cout<<"Yes";	
	return 0;
}

https://www.luogu.com.cn/article/ucgflxsm

posted @ 2026-10-12 11:51  Ivan422  阅读(2)  评论(0)    收藏  举报