• bzoj 1185: [HNOI2007]最小矩形覆盖


    %%hzwer,,可以通过蹩脚的画图法发现,矩形的一边会和凸包一边重合。所以就可以枚举边,然后在用旋转卡壳的方法求出左边界,上边界,右边界就是当前的最小面积。

    这题细节太神了、、、(应该先做下一题,,,)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #define eps 1e-8
     5 using namespace std;
     6 double ans=1e60;
     7 int n,top;
     8 struct point{
     9     double x,y;
    10     point(){}
    11     point(double _x, double _y):x(_x),y(_y){}
    12     friend bool operator < (point a, point b){
    13         return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;
    14     }
    15     friend bool operator == (point a, point b){
    16         return fabs(a.x-b.x)<eps && fabs(a.y-b.y)<eps;
    17     }
    18     friend bool operator != (point a, point b){
    19         return !(a==b);
    20     }
    21     friend point operator + (point a, point b){
    22         return point(a.x+b.x,a.y+b.y);
    23     }
    24     friend point operator - (point a, point b){
    25         return point (a.x-b.x,a.y-b.y);
    26     }
    27     friend point operator * (point a, double b){
    28         return point (a.x*b,a.y*b);
    29     }
    30     friend double operator * (point a, point b){
    31         return a.x*b.y-a.y*b.x;
    32     }
    33     friend double operator / (point a, point b){
    34         return a.x*b.x+a.y*b.y;
    35     }
    36     friend double dis(point a){
    37         return sqrt(a.x*a.x+a.y*a.y);
    38     }
    39 }p[50005],q[50005],t[5];
    40 bool cmp(point a, point b)
    41 {
    42     double t=(a-p[1])*(b-p[1]);
    43     if (fabs(t)<eps) return dis(p[1]-a)-dis(p[1]-b)<0;
    44     return t>0;
    45 }
    46 void Graham()
    47 {
    48     for (int i=2; i<=n; i++)
    49         if (p[i]<p[1]) swap(p[1],p[i]);
    50     sort(p+2,p+n+1,cmp);
    51     q[++top]=p[1]; 
    52     for (int i=2; i<=n; i++)
    53     {
    54         while (top>1 && (q[top]-q[top-1])*(p[i]-q[top])<eps) top--;
    55         q[++top]=p[i];
    56     } 
    57     q[0]=q[top];
    58 }
    59 void RC()
    60 {
    61     int l=1,r=1,p=1;
    62     double L,R,D,H;
    63     for (int i=0; i<top; i++)
    64     {
    65         D=dis(q[i]-q[i+1]);
    66         while ((q[i+1]-q[i])*(q[p+1]-q[i])-(q[i+1]-q[i])*(q[p]-q[i])>-eps) p=(p+1)%top;
    67         while ((q[i+1]-q[i])/(q[r+1]-q[i])-(q[i+1]-q[i])/(q[r]-q[i])>-eps) r=(r+1)%top;
    68         if (i==0) l=r;
    69         while ((q[i+1]-q[i])/(q[l+1]-q[i])-(q[i+1]-q[i])/(q[l]-q[i])<eps) l=(l+1)%top;
    70         L=(q[i+1]-q[i])/(q[l]-q[i])/D; 
    71         R=(q[i+1]-q[i])/(q[r]-q[i])/D;
    72         H=(q[i+1]-q[i])*(q[p]-q[i])/D;
    73         double tmp=fabs(H)*(R-L);
    74         if (tmp<ans)
    75         {
    76             ans=tmp;
    77             t[0]=q[i]+(q[i+1]-q[i])*(R/D);
    78             t[1]=t[0]+(q[r]-t[0])*(H/dis(t[0]-q[r]));
    79             t[2]=t[1]-(t[0]-q[i])*((R-L)/dis(q[i]-t[0]));
    80             t[3]=t[2]-(t[1]-t[0]);
    81         }
    82     }
    83 }
    84 int main()
    85 {
    86     scanf("%d",&n);
    87     for (int i=1; i<=n; i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    88     Graham(); RC();
    89     printf("%.5lf
    ",ans);
    90     int fir=0;
    91     for (int i=1; i<=3; i++)
    92         if (t[i]<t[fir]) fir=i;
    93     for (int i=0; i<=3; i++)
    94         printf("%.5lf %.5lf
    ",t[(i+fir)%4].x,t[(i+fir)%4].y);
    95     return 0;
    96 }
  • 相关阅读:
    关于label和span设置width无效问题解决方法
    CSS 去掉点li 的点
    margin标记可以带一个、二个、三个、四个参数,各有不同的含义。
    MyEclipse下打开ftl文件
    创业企业如何定制商业模式:把握不同行业生命周期,9大要素集中进行创新【转】
    WEB缓存初探
    word 2013如何从某一页开始插入页码
    Ubuntu 16.04 安装jdk
    vmware ubuntu安装vmware tools
    JSP学习
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6488622.html
Copyright © 2020-2023  润新知