Codeforces Gym 100625G Getting Through

G Getting Through

A long and straight corridor is fitted with a number of sensors. Each sensor has a certain range within which it can detect objects or persons. If a part of an object is within the sensor’s range, an alarm will go off. Otherwise, nothing will happen.

Ethan needs to traverse this corridor in order to do some spy stuff at the other end. The question is, can he pass through the corridor without being detected? Can he fit so easily that he can bring some equipment along, or does he have to wear some tight clothing? Or can he perhaps sent a robot through instead?

We model the corridor as being two-dimensional (we ignore the height), bounded by two straight lines. Each sensor is located inside the corridor or on a wall. Their scopes are well in between the two ends of the corridor. We model the person or robot going through as a circle. Given the layout, what is the maximum radius this circle can have so that it is possible to negotiate the corridor without being detected?


Input

On the first line one positive number: the number of test cases, at most 100. After that per test case:

· one line with a single integer w (1 ≤ w ≤ 100 000): the width of the corridor. The two walls are given by the lines x = 0 and x = w.

· one line with a single integer n (0 ≤ n ≤ 1 000): the number of sensors in the corridor.· n lines with three space-separated integers x, y and r (0 ≤ x ≤ w, -100 000 ≤ y ≤

100 000 and 1 ≤ r ≤ 100 000): the location and the range of each sensor, respectively.

The two ends of the corridor are at y = -∞ and y = +∞, or in less technical terms, they are far beyond the scope of all the sensors.


Output

Per test case:

· one line with one floating point number: the radius of the largest circular object (or per- son) that could pass through the corridor without being detected, assuming the object can (be) move(d) with absolute precision. If nothing could possibly get through, the output should be zero. The number should be accurate up to 10-6 absolute precision.

Sample in- and output


Input

3

10

2
2 0 3
7 12 4
10
2
2 0 3
7 8 4
10
2
2 0 3
7 4 4

Output


1.5
1.216991
0

題意:給定兩堵牆和一些哨兵,每個哨兵有他們監視的區域(一個圓),給定這個圓的半徑。要問從兩堵牆之間通過的人的最大半徑是多少,具體看圖。

題解:先把任意兩個點之間連一條邊,邊長爲兩圓心距離減去兩圓半徑。然後對於每個圓,連兩條到兩堵牆的邊。把這些邊按變長排序,從小到大掃一遍。掃過的點用並查集相連,並且用max更新答案。如果最後答案是負值那麼說明無法穿過。注意,兩堵牆之間要連一條邊。

/* written by jiefangxuanyan */
#include <cstdio>
#include <algorithm>
#include <cmath>
const int N=1100;
struct item{
	int a,b;
	double l;
	item(){}
	item(int a,int b,double l):a(a),b(b),l(l){}
	bool operator<(const item &x)const{
		return l<x.l;
	}
}lns[N*N];
struct point{
	int x,y,r;
	double dis(const point &p)const{
		double dx=x-p.x,dy=y-p.y;
		return sqrt(dx*dx+dy*dy)-r-p.r;
	}
}in[N];
int fa[N];
int find(int a){
	if(fa[a]==a){
		return a;
	}
	int r=find(fa[a]);
	fa[a]=r;
	return r;
}
int main(){
	int cn;
	scanf("%d",&cn);
	for(int ci=0;ci<cn;ci++){
		int w,n;
		scanf("%d%d",&w,&n);
		for(int i=0;i<n;i++){
			scanf("%d%d%d",&in[i].x,&in[i].y,&in[i].r);
		}
		int cnt=0;
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				lns[cnt++]=item(i,j,in[i].dis(in[j]));
			}
		}
		for(int i=0;i<n;i++){
			lns[cnt++]=item(i,n,in[i].x-in[i].r);
			lns[cnt++]=item(i,n+1,w-in[i].x-in[i].r);
		}
		lns[cnt++]=item(n,n+1,w);
		std::sort(lns,lns+cnt);
		double s=0;
		for(int i=0;i<=n+1;i++){
			fa[i]=i;
		}
		for(int i=0;i<cnt&&find(n)!=find(n+1);i++){
			int a=find(lns[i].a),b=find(lns[i].b);
			if(a!=b){
				fa[b]=a;
				s=std::max(lns[i].l,s);
			}
		}
		printf("%.10f\n",s/2);
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章