AT_abc317_e [ABC317E] Avoid Eye Contact 题解

提供一个非常无脑但不太好写的做法。

考虑每一个点是否在一个人视线中,只需要考虑四个方向不遇到障碍物的情况下第一个人的方向即可。

那就直接四个方向,每个方向二分一次,找到那个人的位置就做完了。复杂度 O(n2logn)O(n^2 \log n),假设 n,mn,m 同阶。

#include <bits/stdc++.h>
using namespace std;
//#define int long long

const int N = 2005, MOD = 1e9 + 7; // Remember to change

int n, m;
char c[N][N];

namespace FastIo
{
	#define QUICKCIN ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
	int read()
	{
		char ch = getchar();
		int x = 0, f = 1;
		while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
		while (ch == '-')
		{
			f = -f;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9')
		{
			x = (x << 1) + (x << 3) + (ch ^ 48);
			ch = getchar();
		}
		return x * f;
	}
	template<class T>
	void write(T x)
	{
		if (x < 0)
		{
			putchar('-');
			x = -x;
		}
		if (x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
	template<class T>
	void writeln(T x)
	{
		write(x);
		putchar('\n');
	}
}

int sx, sy, ex, ey;
bool can[N][N];

int s1[N][N],s2[N][N],s3[N][N],s4[N][N],s5[N][N],s6[N][N];

int dis[N][N];

int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};

void bfs()
{
	queue<pair<int, int> > q;
	q.push(make_pair(sx,sy));
	memset(dis,-1,sizeof dis);
	dis[sx][sy]=0;
	while(q.size())
	{
		auto u=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			int nx=u.first+dx[i],ny=u.second+dy[i];
			if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&can[nx][ny])
			{
				if(dis[nx][ny]==-1)
				{
					dis[nx][ny]=dis[u.first][u.second]+1;
					q.push(make_pair(nx,ny));
				}
			}
		}
	}
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++) 
		{
			can[i][j]=1;
			cin>>c[i][j];
			if(c[i][j]=='S') sx=i,sy=j;
			else if(c[i][j]=='G') ex=i,ey=j;
			else if(c[i][j]=='#'||c[i][j]=='>'||c[i][j]=='v'||c[i][j]=='<'||c[i][j]=='^') can[i][j]=0;
			s1[i][j]=s1[i][j-1]+s1[i-1][j]-s1[i-1][j-1]+(c[i][j]=='#');
			s2[i][j]=s2[i][j-1]+s2[i-1][j]-s2[i-1][j-1]+(c[i][j]=='>'||c[i][j]=='v'||c[i][j]=='<'||c[i][j]=='^');
			s3[i][j]=s3[i][j-1]+s3[i-1][j]-s3[i-1][j-1]+(c[i][j]=='>');
			s4[i][j]=s4[i][j-1]+s4[i-1][j]-s4[i-1][j-1]+(c[i][j]=='v');
			s5[i][j]=s5[i][j-1]+s5[i-1][j]-s5[i-1][j-1]+(c[i][j]=='<');
			s6[i][j]=s6[i][j-1]+s6[i-1][j]-s6[i-1][j-1]+(c[i][j]=='^');
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(c[i][j]=='.'&&can[i][j])
			{
				// 从上方
				bool f=0;
				int l=1,r=i-1;
				while(l<=r)
				{
					int mid=l+r>>1;	
					if(s1[i][j]-s1[i][j-1]-(s1[mid-1][j]-s1[mid-1][j-1])>=1)
					{
						l=mid+1;
					}
					else if(s2[i][j]-s2[i][j-1]-(s2[mid-1][j]-s2[mid-1][j-1])>1)
					{
						l=mid+1;
					}
					else
					{
						if(s4[i][j]-s4[i][j-1]-(s4[mid-1][j]-s4[mid-1][j-1])>0)
						{
							f=1;
							break;
						}
						r=mid-1;
					}
				}
				// 从左边
				l=1,r=j-1;
				while(l<=r)
				{
					int mid=l+r>>1;
					if(s1[i][j]-s1[i-1][j]-(s1[i][mid-1]-s1[i-1][mid-1])>=1)
					{
						l=mid+1;
					}
					else if(s2[i][j]-s2[i-1][j]-(s2[i][mid-1]-s2[i-1][mid-1])>1)
					{
						l=mid+1;
					}
					else
					{
						if(s3[i][j]-s3[i-1][j]-(s3[i][mid-1]-s3[i-1][mid-1])>0)
						{
							f=1;
							break;
						}
						r=mid-1;
					}
				} 
				// 从下方
				l=i+1,r=n;
				while(l<=r)
				{
					int mid=l+r>>1;
					if(s1[mid][j]-s1[mid][j-1]-(s1[i-1][j]-s1[i-1][j-1])>=1)
					{
						r=mid-1;
					}
					else if(s2[mid][j]-s2[mid][j-1]-(s2[i-1][j]-s2[i-1][j-1])>1)
					{
						r=mid-1;
					}
					else
					{
						if(s6[mid][j]-s6[mid][j-1]-(s6[i-1][j]-s6[i-1][j-1])>0)
						{
							f=1;
							break;
						}
						l=mid+1;
					}
				} 
				//从右边
				l=j+1,r=m;
				while(l<=r)
				{
					int mid=l+r>>1;
					if(s1[i][mid]-s1[i-1][mid]-(s1[i][j-1]-s1[i-1][j-1])>=1)
					{
						r=mid-1;
					}
					else if(s2[i][mid]-s2[i-1][mid]-(s2[i][j-1]-s2[i-1][j-1])>1)
					{
						r=mid-1;
					}
					else
					{
						if(s5[i][mid]-s5[i-1][mid]-(s5[i][j-1]-s5[i-1][j-1])>0)
						{
							f=1;
							break;
						}
						l=mid+1;
					}
				 }
				can[i][j]=!f;
			}
		}
	}
	bfs();
	cout<<dis[ex][ey]<<"\n";
	return 0;
}

/*
7 7
S..>.>.
G.^.#<.
....#<<
##<<#<<
##.#<##
..#<>.^
^.>.#.<
*/
posted @   HappyBobb  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示