洛谷 P7380 [COCI 2018/2019 #6] Konj 题解

P7380 [COCI 2018/2019 #6] Konj 题解

题目传送门

题意

给定 \(n\) 条线段两端端点坐标,保证一定与 \(x\) 轴或 \(y\) 轴平行。求最小的矩阵能表示出从点 \(T\) 出发到达的所有点。

如果两条线段相交或间接可以走到则称这两条线段相连。

思路

注意到虽然 \(n\) 十分之大,但端点坐标却在 \(0\sim 300\) 之间,所以可以考虑维护点。

不难想到对于每条线段,都在图上打上标记,表示这条线段的存在。最后再从点 \(T\) 出发,搜索搜一下就可以得到答案矩阵。

即对于每个点 \((x,y)\),若有至少一条线段经过,则 vis[x][y]=1。最后搜索时就从点 \(T\) 遍历四连通块即可。

但这样显然是不行的。因为如果两条线段相邻但不相交,但搜索时会被判为联通。

hack 如下:

...*
...*
####

其中 #* 代表不同的两条线段。且两条线段没有交点。

那么如何优化?

注意到四个方向并不多,可以对于每个点判断四个方向可不可以走。

显然如果在一条线段内,那么是可以按照这条线段的走向走的,即有两个方向可以走。

显然如果是线段的端点,则只有一个方向可以走,特判一下就行啦。

最后因为题目中的 \(y\) 坐标是按照平面直角坐标系来的,所以输出的时候要注意一下。

因为题目还要求说是最小的矩阵,所以在搜索中维护一下 \(x\) 坐标和 \(y\) 坐标的最大最小值即可。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,M=305,nxt[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
int n,Tx,Ty,maxx,maxy,minx=305,miny=305;
bool g[M][M][5];//1 up 2 down 3 left 4 right
bool vis[M][M];
struct L{
	int x1,y1,x2,y2;
}l[N];
void addg(int i)
{
	int x1=l[i].x1,x2=l[i].x2,y1=l[i].y1,y2=l[i].y2;
	if(x1==x2)// // y 
	{
		if(y1<y2)swap(y1,y2);//方便起见
		g[x1][y1][2]=1;g[x1][y2][1]=1;
		for(int y=y2+1;y<y1;++y)
			g[x1][y][1]=g[x1][y][2]=1;//竖着走的线段可以上下两边
		return;
	}
	// // x
	if(x1>x2)swap(x1,x2);//方便
	g[x1][y1][4]=g[x2][y1][3]=1;
	for(int x=x1+1;x<x2;++x)
		g[x][y1][3]=g[x][y1][4]=1; //横着走的线段可以左右两边
	return;
}
void dfs(int x,int y)
{
	vis[x][y]=1;
	maxx=max(maxx,x);minx=min(minx,x);
	maxy=max(maxy,y);miny=min(miny,y);
	for(int i=0;i<4;++i)
	{
		int tx=x+nxt[i][0],ty=y+nxt[i][1];
		if(tx<0||tx>300||ty<0||ty>300||vis[tx][ty])continue;
		if(!i)//up
			if(!g[x][y][1])continue;
		if(i==1)//right
			if(!g[x][y][4])continue;
		if(i==2)//left
			if(!g[x][y][3])continue;
		if(i==3)//down
			if(!g[x][y][2])continue;
		dfs(tx,ty);
	}
	return;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;++i)
		cin>>l[i].x1>>l[i].y1>>l[i].x2>>l[i].y2;
	cin>>Tx>>Ty;
	for(int i=1;i<=n;++i)
		addg(i);
	dfs(Tx,Ty);
	for(int y=maxy;y>=miny;--y)//注意啦!!是按照平面直角坐标系的y坐标
	{
		for(int x=minx;x<=maxx;++x)
			cout<<(vis[x][y]?'#':'.');
		cout<<'\n';
	}
	return 0;
}

AC 记录。

posted @ 2025-10-20 19:16  Atserckcn  阅读(4)  评论(0)    收藏  举报