Network(计算几何:推规律+暴力+贪心)

本文探讨了一种在有限网络条件下,最大化网络覆盖范围并最小化路由器与主人房屋距离的算法。通过三种情况分析,实现最优网络部署,确保所有英雄能够接入网络。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Link:http://acm.hdu.edu.cn/showproblem.php?pid=4766


Network

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 713    Accepted Submission(s): 171


Problem Description
With the help of the Ares L, the Emperor of Law and some stars of the future, General M succeeded in setting foot on the mountain, and had set up a kingdom, known as ACMSYSU. In order to reward these founding heroes, General M decided to share her network.
General M has manufactured a router. One can use this network if the Euclidean distance between his/her house and the router is not greater than d. Because of General M's excellent technology, the distance between her house and the router can be infinite.
There are n heroes in the kingdom besides General M. General M is not an eccentric person, so she hopes everyone can use the network. Because the farther the router is away from her house, the worse the signal, General M wants the router being as close to her house as possible. Please help General M place the router so that the distance between her house and the router is minimized, and every one can use the router. You just need to tell General M the minimum distance.
 

Input
The input will consist of multiple test cases. 
For each case, the first line contains 3 integers x, y and d, which represent that the General M's house locates at the point (x, y) and one can use the network if his/her distance to the router is not greater than d.
The second line is a positive integer n, the number of heroes of the kingdom.
Then n lines follow. Each line has 2 integers x_i and y_i, indicating that the i-th hero locates at point (x_i, y_i)。

All integers in the input satisfy that their absolute values are less than or equal to 10^5, and 1<=n<=10^3.
 

Output
For each case, output a real number which indicates the minimum distance between the General M's house and the router, to two decimal places.
If it is impossible to share a network which can cover everyone, output an 'X' (without the single quote).
 

Sample Input
  
  
0 0 5 2 5 3 5 -3 0 0 1 2 5 3 5 -3
 

Sample Output
  
  
1.00 X
 

Source
 





题意  :就是找到一个 位置 使得路由器可以覆盖所有英雄    可以不覆盖主人自己, 找到距离 主人房子最近的位置,距离为多少。


没想到  其实是道水题啊!!  分三个情况讨论:


第一个情况    如果  把主人的位置放上路由器 可以 覆盖到所有英雄,则答案出来了 0( 一个 半径为 d 的圆,边界上没有点);


第二个情况    考虑  圆上只有一个点,这个圆只受到该点的约束( 则圆心在  连线上);


第三个情况   两个点  或者更多点确定那个圆, 则当两个点或者更多的点都距离为d 时确定那个圆心;因为如果那个点的距离没有到d   证明我还可以更靠近一点房子


AC code:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<vector>
#define eps 1e-9
using namespace std;
const double PI=acos( -1.0 );
inline int dcmp( double x ){if( abs(x) < eps )return 0;else return x<0?-1:1;}
struct point{
   double x,y;
   point( double x = 0,double y = 0 ):x(x),y(y){}
}node[112345];
typedef point Vector;
typedef vector<point>ploygon;
inline point operator+( point a,point b ){ return point(a.x+b.x,a.y+b.y); }
inline point operator-( point a,point b ){ return point(a.x-b.x,a.y-b.y); }
inline point operator*( point a,double p){ return point(a.x*p,a.y*p); }
inline point operator/( point a,double p){ return point(a.x/p,a.y/p); }
inline bool operator< ( const point &a,const point &b ){return  a.x<b.x||(a.x==b.x&&a.y<b.y);}
inline bool operator==( const point &a,const point &b ){return (dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0);}
inline bool operator!=( const point &a,const point &b ){return a==b?false:true;}

inline double Dot( point a,point b ){ return a.x*b.x + a.y*b.y; }
inline double Cross( point a,point b ){ return a.x*b.y - a.y*b.x; }
inline double Length( point a ){ return sqrt(Dot(a,a)); }
inline double Angle( point a,point b ){
      double right = Dot(a,b)/Length(a)/Length(b);
      return acos(right);
}
inline point Rotate( point a,double rad ){
    return point( a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad+a.y*cos(rad)) );
}
point A[1123]; int N; double dis;
bool work( point temp )
{
    for( int i = 1; i <= N; i++ )
    if( Length( A[i]-temp ) > dis && abs(Length( A[i] - temp ) - dis) > eps ){
    return false;}
    return true;
}
int main()
{
	while( scanf("%lf%lf%lf",&A[0].x,&A[0].y,&dis) !=EOF)
	{
		scanf("%d",&N);
		for(int i=1;i<=N;i++)
		{
			scanf("%lf%lf",&A[i].x,&A[i].y);
		}
		if(work(A[0]))
		{
			 puts("0.00");
		}
		else
		{
			double Min=(1<<30);
			for(int i=1;i<=N;i++)
			{
				point temp=A[i]+(A[0]-A[i])*(dis/Length(A[0]-A[i]));//圆心 
				if(Min>Length(temp-A[0]))
				{
					if(work(temp))
					{
						Min=Length(temp-A[0]);
					}
				}
			}
			for(int i=1;i<=N;i++)
			{
				for(int j=i+1;j<=N;j++)
				{
					point temp = (A[i]+A[j])/2.0;//线段中点 
					double D = Length(A[i]-A[j])*0.5;//线段一半的长度
					Vector now1=Rotate(A[i]-A[j],PI/2.0)*sqrt(dis*dis-D*D)/(D*2.0);
					Vector now2=Rotate(A[i]-A[j],-PI/2.0)*sqrt(dis*dis-D*D)/(D*2.0);
					//过两点满足圆心与这两点距离为dis的圆心有两个 
					point temp1=temp+now1;
					point temp2=temp+now2;
				    if( Length( temp1-A[0] ) < Min )
					{
						if( work( temp1 ) )
						{
							Min=Length( temp1-A[0] );
						}
					}
					if(Length( temp2-A[0] ) < Min)
					{
						if( work( temp2 ) )
						{
							Min=Length( temp2-A[0] );
						}
					} 
				}
			}
		
			if( Min==(1<<30) ) puts("X");
			else printf("%.2lf\n",Min);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林下的码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值