【BOI2012】Mobile(mobile)
2017-10-07 22:07
423 查看
题目
在一个平面内有n个基站,每个基站有个坐标(xi,yi),现在要给每个基站设定一个相同的值,使基站覆盖x轴上(0,m)的所有点,求这个值最小要是多少。PS:输入的点已按x为第一关键字y为第二关键字排序。
题解
①过滤无用点。②在此基础上利用单调栈维护对答案有用的点。③计算答案。所谓无用点,就是当x相同时,abs(y)不是最小的点。(这很显然)
考虑正确答案的规律。
如果面前有一道题目,十分地棘手,那么很可能会有一个结论让你推,那请你根据题目给你的条件猜测一下这个结论是什么。这一点很重要。
假设有这么三个点A,B,C,设(x1,0)为AB的中垂线与X轴的交点,(x2,0)为BC的中垂线与X轴的交点。若x2<x1则点B为没用的点。详见图①。
x轴下方红色括号括起来的部分是A点比B点优的部分,绿色代表B比A优。
x轴下方绿色括号括起来的部分是B点比C点优的部分,绿色代表C比B优。
由于YC<YB,所以黄色部分优于其下方绿色部分。
很显然,上方绿色部分没有其下方的红色部分优。所以淘汰掉B点。
维护个单调栈就可以实现步骤②。
最后统计的答案大致为两点(最后筛出来的)中垂线与X轴的交点与其中一点的距离的最大值。
PS:注意边界。这是个很恶心的地方。
我们可以知道中垂线与X轴的交点的横坐标x单调递增。所以
①刚刚x进入[0,L]时,判断一下ans=max(ans,min(dis(0,0,x[d[i−1]],y[d[i−1]]),dis(0,0,x[d[i]],y[d[i]])))
②x∈[0,L],ans=max(ans,dis(temp,0,x[d[i]],y[d[i]]))
③x刚刚出[0,L]时,判断一下ans=max(ans,min(dis(L,0,x[d[i−1]],y[d[i−1]]),dis(L,0,x[d[i]],y[d[i]])))
然而还有一个更坑爹的地方,一定要考虑到。
④x一直∈[0,L]时,
ans=max(ans,dis(0,0,x[d[1]],y[d[1]]))
ans=max(ans,dis(L,0,x[d[tail]],y[d[tail]]))
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define N 1000010 #define DB double #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; int i,j,k,l,n,m,tot,last; DB x ,y ,L; DB K,B,X1,Y1,X,Y; DB temp,temp1,ans,mx; int head,tail,d ; DB point(int i,int j){ DB K,X1,Y1,B; K=(y[i]-y[j])/(x[i]-x[j]); if(K==0){ return (x[j]+x[i])/2; } K=-1/K; X1=(x[i]+x[j])/2; Y1=(y[i]+y[j])/2; B=Y1-X1*K; return -B/K; } DB dis(DB X0,DB Y0,DB X1,DB Y1){return sqrt((X0-X1)*(X0-X1)+(Y0-Y1)*(Y0-Y1));} int main(){ freopen("mobile.in","r",stdin); freopen("mobile.out","w",stdout); scanf("%d%lf",&n,&L); x[0]=-2147483647; fo(i,1,n){ scanf("%lf%lf",&X,&Y); if(X>x[tot]){ tot++; x[tot]=X; y[tot]=Y; } else if(X==x[tot])if(abs(Y)<abs(y[tot]))y[tot]=Y; } last=0; d[1]=0; tail=0; fo(i,1,tot){ while (tail>=2 && point(d[tail-1],d[tail])>=point(d[tail],i)) tail--; d[++tail]=i; } ans=-2147483647; temp=point(d[2],d[1]); if(temp>0)ans=max(ans,dis(0,0,x[d[1]],y[d[1]])); fo(i,2,tail){ temp=point(d[i],d[i-1]); if(temp1<0 && temp>=0) ans=max(ans,min(dis(0,0,x[d[i-1]],y[d[i-1]]),dis(0,0,x[d[i]],y[d[i]]))); if(temp>L && temp1<=L){ ans=max(ans,min(dis(L,0,x[d[i-1]],y[d[i-1]]),dis(L,0,x[d[i]],y[d[i]]))); } if(temp>=0&&temp<=L) ans=max(ans,dis(temp,0,x[d[i]],y[d[i]])); temp1=temp; } if(temp<L)ans=max(ans,dis(L,0,x[d[tail]],y[d[tail]])); printf("%.6lf",ans); return 0; }
相关文章推荐
- 【BOI2012】Mobile
- jzoj3636. 【BOI2012】Mobile(mobile)
- 【JZOJ3623】【BOI2012】Mobile
- 【JZOJ3636】【BOI2012】Mobile(mobile)
- {题解}[jzoj3636]【BOI2012】Mobile(mobile)
- 【BOI2012】Mobile
- JZOJ3636. 【BOI2012】Mobile
- 【JZOJ 3636】【BOI2012】Mobile
- JZOJ 3636. 【BOI2012】Mobile
- 【BOI2012】Mobile(mobile)
- JZOJ 【BOI2012】Peaks
- F2FS – A New Flash File System for Mobile Devices – ELCE 2012
- WindowsPhone第三方控件-Resco MobileForms Toolkit 2012
- WindowsPhone第三方控件-Resco MobileForms Toolkit 2012
- WindowsPhone第三方控件-Resco MobileForms Toolkit 2012
- JZOJ 3635.【BOI2012】Peaks
- Mobile GIS的2012和未来
- 【独家对话】Esri移动产品经理David Cardella谈Mobile GIS的2012和未来
- 【BOI2012】Mobile jzoj 3636 计算几何
- 【BOI2012】Peaks