您的位置:首页 > 其它

【JZOJ3623】【BOI2012】Mobile

2017-03-04 21:21 671 查看

Description

著名的手机网络运营商Totalphone 修建了若干基站收发台,以用于把信号网络覆盖一条新建的高速公路。因为Totalphone 的程序员总是很马虎的,所以,基站的传功功率不能独立设置,只能将所有新基站的功率设置为一个相同的值。为了让能源的消耗尽量少,公司希望知道公路中任意点到最近基站距离的最大值。

Data Constraint

总值25 分的数据满足N<=5000

总值100 分的数据满足N<=1000000。Time Limits: 500 ms。

所有给出的点都互不相同。点按照x坐标不下降排列。如果两个点的x坐标相同,那么它们之间按照y坐标的升序排列。

Solution

学过数学的都知道,两点之间的垂直平分线上的点到两点的距离相等……

于是我们发现,对于不在同x轴两个点a,b(xa< xb)假如它们的垂直平分线交x轴于(t,0),那么在x<=t时,x轴上的点一定是到点a更短,反之到b更短。那么现在有三点a,b,c(xa< xb< xc),假如ab的垂直平分线交x轴于(x1,0),bc的垂直平分线交x轴于(x2,0),假如满足(x1>x2),那么b就是没用的点,证明显然,画画图就知道。

于是我们现在顺序加入点进入队列,每次判断队尾的点是否还有用,没用就把队尾的点踢出队列,同时判断队首的于队首+1的点的垂直平分线与x轴的交点是否大于0,否则就把队首踢出队列。最后扫一下队列中相邻两个的垂直平分线与x轴的交点到该点的距离即可。复杂度O(N).

P.S. 要注意10^6要打读入优化!!!

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define db double
using namespace std;
const int maxn=1e6+5;
int d[maxn];
int n,i,t,j,k,l,num;
db ans,x[maxn],y[maxn],z,p,xx,yy,m,x2,y2;
char ch;
db sqr(db x){
return x*x;
}
int pan(int a,int b,int c){
return (sqr(y[a])+sqr(x[a])-sqr(y[b])-sqr(x[b]))*(x[b]-x[c])>(sqr(y[b])+sqr(x[b])-sqr(y[c])-sqr(x[c]))*(x[a]-x[b]);
}
db dg(int a,int b){
return (sqr(y[a])+sqr(x[a])-sqr(y[b])-sqr(x[b]))/(2*(x[a]-x[b]));
}
db dg1(){
int x=0,y=1;ch=getchar();
if (ch=='-') ch=getchar(),y=-1;
while (ch>=48 && ch<=57) x=x*10+(ch-48),ch=getchar();
return x*y;
}
int main(){
freopen("mobile.in","r",stdin);freopen("mobile.out","w",stdout);
//  freopen("data.in","r",stdin);
scanf("%d%lf\n",&n,&m);d[0]=1;z=1e9;x2=y2=1000000000000000000;
for (i=1;i<=n;i++){
xx=dg1();yy=dg1();
if (xx!=z){
if (i>1) x[++num]=z,y[num]=p,x2=min(x2,sqrt(sqr(z)+sqr(p))),y2=min(y2,sqrt(sqr(z-m)+sqr(p)));
z=xx;p=abs(yy);
}else p=min(p,abs(yy));
}
x[++num]=z,y[num]=p,x2=min(x2,sqrt(sqr(z)+sqr(p))),y2=min(y2,sqrt(sqr(z-m)+sqr(p)));
ans=max(y2,x2);n=num;num=0;
for (i=1;i<=n;i++){
while (num>d[0] && dg(d[d[0]],d[d[0]+1])<0) d[0]++;
while (num>d[0] && pan(d[num-1],d[num],i)) num--;
d[++num]=i;
}
for (i=d[0]+1;i<=num;i++){
z=dg(d[i-1],d[i]);
if (z>m)break;
ans=max(ans,sqrt(sqr(z-x[d[i]])+sqr(y[d[i]])));
}
printf("%.5lf\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: