bzoj 4570: [Scoi2016]妖怪

给神题跪烂烂

贴个题解吧:http://www.cnblogs.com/Skyminer/p/6431746.html

把那个奇怪的式子搞成直线可以看成,然后求凸包还是没想到。。。太辣鸡了2333

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 #define inf 1e60
 4 using namespace std;
 5 inline int ra()
 6 {
 7     int x=0,f=1; char ch=getchar();
 8     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 9     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
10     return x*f;
11 }
12 
13 const int maxn=1000005;
14 
15 int n,top;
16 struct point{LL x,y;}p[maxn],st[maxn];  
17 double ans=inf,k1,k2,k;  
18 
19 bool cmp(point a, point b) {return a.x<b.x||(a.x==b.x && a.y<b.y);}
20 point operator - (point a, point b) {return (point){a.x-b.x,a.y-b.y};}
21 LL operator * (point a, point b) {return a.x*b.y-a.y*b.x;}
22 void Graham()
23 {
24     sort(p+1,p+n+1,cmp); st[++top]=p[1];
25     for (int i=2; i<=n; i++)
26     {
27         while (top>=2 && (st[top]-st[top-1])*(p[i]-st[top-1])>=0) top--;
28         st[++top]=p[i];
29     }
30 }
31 
32 double get(point a) {return sqrt((double)a.y/(double)a.x);}
33 double getk(point a, point b) {return -(a.x==b.x?inf:(double)(a.y-b.y)/(double)(a.x-b.x));}
34 double cal(point a, double k) {return k<=0?inf:(double)a.x+a.y+a.x*k+a.y/k;}
35 int main()
36 {
37     n=ra();
38     for (int i=1; i<=n; i++) p[i].x=ra(),p[i].y=ra();
39     Graham();
40     if (top==1) {printf("%.4lf\n",cal(st[1],get(st[1]))); return 0;}
41     k2=getk(st[1],st[2]); k=get(st[1]);
42     if (k<=k2) ans=min(ans,cal(st[1],k));
43     k1=getk(st[top-1],st[top]); k=get(st[top]);
44     if (k>=k1) ans=min(ans,cal(st[top],k));
45     ans=min(ans,cal(st[top],k1));
46     for (int i=2; i<=top-1; i++)
47     {
48         k1=getk(st[i-1],st[i]); k2=getk(st[i],st[i+1]); k=get(st[i]);
49         ans=min(ans,cal(st[i],k1));
50         if (k>=k1 && k<=k2) ans=min(ans,cal(st[i],k));
51     }
52     printf("%.4lf\n",ans); 
53 }

 

posted @ 2017-05-03 06:57  ws_ccd  阅读(175)  评论(0编辑  收藏  举报