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 }