Physical Distancing

To prevent the spread of Covid-19, people are asked to keep their distance from other people, who could be infected. Some experts recommend a distance of 2 metres, others 6 feet, and still others 1.5 metres. In some crowded settings, these recommended distances may not be possible. In any setting, maximizing the distance minimizes the risk of getting infected.

You need to walk down a crowded hallway in which other people are standing. Determine the maximum possible distance that you can maintain from all the other people while still being able to navigate from one end of the hallway to the other. (Assume that you and every other person is a point with zero area.)

Input
The first line contains three space-separated integers L,W,N, the length and width of the hallway and the number of people standing in it, with 0<L,W≤100 and 1≤N≤100. Each of these integers is between 0 and 100, inclusive. The following N lines each contain two integers X,Y , the coordinates of the location of each person, with 0≤X≤L and 0≤Y≤W.

Output
Output a single number, the maximum distance that you can maintain from any other person while navigating the length of the hallway. Your answer will be considered correct if the absolute or relative error to the judge’s answer is within 10−4.

Samples
Input 复制
100 100 1
50 50
Output
50.00000000000000
Input 复制
100 2 2
49 0
51 2
Output
1.41421356237310
题意:
给你一个长L宽W的走廊,给你n个点,求一个最大半径,让这些点与这个半径组成的圆圈(可以理解为障碍物)不能形成一个拦截线,阻挡你从走廊的这一端走到另一端;
在这里插入图片描述
在这里插入图片描述
(草图)

思路:
基本上题意理解清楚了,这个题其实没那么难吧*——*
由于答案为浮点数,我们可以进行浮点数二分查找(附上板子)+并查集判断,建议去洛谷做一下奶酪

#include<bits/stdc++.h>
using namespace std;
const double cal=1e-6;
const int N=110;
double x[N],y[N];
double L,W,l,r,mid;
int up[N],down[N];
int father[N];
int n,flag;
int find(int x){
	if(father[x]==x) return x;
	return father[x]=find(father[x]); 
}
void combinue(int x,int y){
	int dx=find(x);
	int dy=find(y);
	if(dx!=dy) father[dx]=dy;
	return ;
}
int ok(){
	for(int i=1;i<=n;i++) father[i]=i;
	int d=0,u=0;
	for(int i=1;i<=n;i++){
		if(y[i]<mid) down[d++]=i;
		if(y[i]+mid>W) up[u++]=i;
		for(int j=1;j<=n;j++){
			double dis=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
			if(dis<=4*mid*mid) combinue(i,j);//这个题相切不相切都可以过
		}
	}
	
	for(int i=0;i<u;i++){
		for(int j=0;j<d;j++){
			int dx=find(up[i]);
			int dy=find(down[j]);
			if(dx==dy) return 0;
		}
	}
	return 1;
}
int main(){
	cin>>L>>W>>n;
	for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
	l=0,r=W;
	while(r-l>cal){
		mid=0.5*(l+r);
		if(ok()) l=mid;
		else r=mid;
	}
	printf("%.14lf",mid);
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值