[bzoj1185] [HNOI2007]最小矩形覆盖

  旋(xuàn)转(zhuàn)卡(kǎ)壳(qiào)(大雾

  抄了黄学长的标程当板子。。

  求凸包后,两对平行线卡来卡去..上下一对的直接用单峰性质,左右一对的也是...就看到底边的投影长,这个用数量积除以底边长。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define ll long long
 7 #define d double
 8 using namespace std;
 9 const int maxn=52333;
10 const d eps=1e-8;
11 struct P{
12     d x,y;
13 }a[maxn],st[maxn],t[4];int tp;
14 int i,j,k,n,m;
15 int next[maxn];
16 d ans=1e60;
17 
18 P operator +(P a,P b){return (P){a.x+b.x,a.y+b.y};}
19 P operator -(P a,P b){return (P){a.x-b.x,a.y-b.y};}
20 P operator *(P a,d b){return (P){a.x*b,a.y*b};}
21 
22 d operator ^(P a,P b){return a.x*b.y-b.x*a.y;}
23 d operator *(P a,P b){return a.x*b.x+a.y*b.y;}
24 
25 
26 
27 bool operator <(P a,P b){return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;}
28 
29 int ra;char rx;
30 inline int read(){
31     rx=getchar(),ra=0;
32     while(rx<'0'||rx>'9')rx=getchar();
33     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
34 }
35 
36 d dis(P a){return sqrt(a.x*a.x+a.y*a.y);}
37 inline void calc(){
38     int l=1,r=1,p=1,i;
39     d L,R,D,H,tmp;
40     P now;
41     for(i=0;i<tp;i++)next[i]=(i+1==tp)?0:i+1;
42     for(i=0;i<tp;i++){
43         now=st[i+1]-st[i],
44         D=dis(now);
45         while( (now^(st[p+1]-st[i])) > (now^(st[p]-st[i]))-eps )p=next[p];
46         while( now*(st[r+1]-st[i]) > now*(st[r]-st[i])-eps )r=next[r];
47         if(!i)l=r;
48         while( now*(st[l+1]-st[i]) < now*(st[l]-st[i])+eps )l=next[l];
49 //        printf("   %d %d %d\n",l,r,p);
50         L=now*(st[l]-st[i])/D,R=now*(st[r]-st[i])/D,
51         H=fabs( (now^(st[p]-st[i]))/D );
52 //        printf("     %.2lf %.2lf %.2lf    %.2lf\n",L,R,H,D);
53         tmp=(R-L)*H;
54         if(tmp<ans)
55             ans=tmp,
56             t[0]=st[i]+(st[i+1]-st[i])*(R/D),
57             t[1]=t[0]+(st[r]-t[0])*(H/dis(t[0]-st[r])),
58             t[2]=t[1]-(t[0]-st[i])*((R-L)/dis(st[i]-t[0])),
59             t[3]=t[2]-(t[1]-t[0]);
60     }
61 }
62 bool cmp(P x,P y){
63     d tmp=(x-a[1])^(y-a[1]);
64     if(fabs(tmp)<eps)return dis(a[1]-x)-dis(a[1]-y)<=-eps;
65     return tmp>=eps;
66 }
67 inline void graham(){
68     register int i;
69     for(i=2;i<=n;i++)if(a[i]<a[1])swap(a[i],a[1]);
70     sort(a+2,a+n+1,cmp);
71     st[++tp]=a[1];
72     for(i=2;i<=n;st[++tp]=a[i],i++)
73         while(tp>1&&((st[tp]-st[tp-1])^(a[i]-st[tp]))<eps)tp--;//,puts("..");
74     st[0]=st[tp];
75 }
76 
77 
78 int main(){
79     n=read();
80     for(i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
81     graham();
82 //    for(i=1;i<=tp;i++)printf("  %.3lf %.3lf\n",st[i].x,st[i].y);
83 //    for(i=1;i<=n;i++)printf("       %.3lf %.3lf\n",a[i].x,a[i].y);
84     calc();
85     printf("%.5lf\n",ans);
86     int mn=0;
87     for(i=1;i<4;i++)if(t[i]<t[mn])mn=i;
88     for(i=0;i<4;i++)printf("%.5lf %.5lf\n",t[(i+mn)&3].x,t[(i+mn)&3].y);
89 }
View Code

 

posted @ 2016-07-05 19:12  czllgzmzl  阅读(215)  评论(0编辑  收藏  举报