zoukankan      html  css  js  c++  java
  • 【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)

    给你一些点,让你用最小的矩形覆盖这些点

    首先有一个结论,矩形的一条边一定在凸包上!!!
    枚举凸包上的边
    用旋转卡壳在凸包上找矩形另外三点。。。
    注意精度问题
      1 #include<cstdio>
      2 #include<cmath>
      3 #include<ctime>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<set>
      9 #define eps 1e-8
     10 #define inf 1000000000
     11 using namespace std;
     12 double ans=1e60;
     13 int n,top;
     14 struct P{
     15     double x,y;
     16     P(){}
     17     P(double _x,double _y):x(_x),y(_y){}
     18     friend bool operator<(P a,P b){
     19         return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;
     20     }
     21     friend bool operator==(P a,P b){
     22         return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;
     23     }
     24     friend bool operator!=(P a,P b){
     25         return !(a==b);
     26     }
     27     friend P operator+(P a,P b){
     28         return P(a.x+b.x,a.y+b.y);
     29     }
     30     friend P operator-(P a,P b){
     31         return P(a.x-b.x,a.y-b.y);
     32     }
     33     friend double operator*(P a,P b){
     34         return a.x*b.y-a.y*b.x;
     35     }
     36     friend P operator*(P a,double b){
     37         return P(a.x*b,a.y*b);
     38     }
     39     friend double operator/(P a,P b){
     40         return a.x*b.x+a.y*b.y;
     41     }
     42     friend double dis(P a){
     43         return sqrt(a.x*a.x+a.y*a.y);
     44     }
     45 }p[50005],q[50005],t[5];
     46 bool cmp(P a,P b)
     47 {
     48     double t=(a-p[1])*(b-p[1]);
     49     if(fabs(t)<eps)return dis(p[1]-a)-dis(p[1]-b)<0;
     50     return t>0;
     51 }
     52 void graham()
     53 {
     54     for(int i=2;i<=n;i++)
     55         if(p[i]<p[1])
     56             swap(p[i],p[1]);
     57     sort(p+2,p+n+1,cmp);
     58     q[++top]=p[1];
     59     for(int i=2;i<=n;i++)
     60     {
     61         while(top>1&&(q[top]-q[top-1])*(p[i]-q[top])<eps)top--;
     62         q[++top]=p[i];
     63     }
     64     q[0]=q[top];
     65 }
     66 void RC()
     67 {
     68     int l=1,r=1,p=1;
     69     double L,R,D,H;
     70     for(int i=0;i<top;i++)
     71     {
     72         D=dis(q[i]-q[i+1]);
     73         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;
     74         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;
     75         if(i==0)l=r;
     76         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;
     77         L=(q[i+1]-q[i])/(q[l]-q[i])/D,R=(q[i+1]-q[i])/(q[r]-q[i])/D;
     78         H=(q[i+1]-q[i])*(q[p]-q[i])/D;
     79         if(H<0)H=-H;
     80         double tmp=(R-L)*H;
     81         if(tmp<ans)
     82         {
     83             ans=tmp;
     84             t[0]=q[i]+(q[i+1]-q[i])*(R/D);
     85             t[1]=t[0]+(q[r]-t[0])*(H/dis(t[0]-q[r]));
     86             t[2]=t[1]-(t[0]-q[i])*((R-L)/dis(q[i]-t[0]));
     87             t[3]=t[2]-(t[1]-t[0]);
     88         }
     89     }
     90 }
     91 int main()
     92 {
     93     scanf("%d",&n);
     94     for(int i=1;i<=n;i++)
     95         scanf("%lf%lf",&p[i].x,&p[i].y);
     96     graham();
     97     RC();
     98     printf("%.5lf
    ",ans);
     99     int fir=0;
    100     for(int i=1;i<=3;i++)
    101         if(t[i]<t[fir])
    102             fir=i;
    103     for(int i=0;i<=3;i++)
    104         printf("%.5lf %.5lf
    ",t[(i+fir)%4].x,t[(i+fir)%4].y);
    105     return 0;
    106 }
  • 相关阅读:
    织梦插件开发
    yiic使用笔记
    yii2.0学习及变化比较(一)
    yii框架设计学习笔记(一)
    Maven生成可以直接运行的jar包的多种方式(转)
    Linux下查看CPU型号,内存大小,硬盘空间的命令(详解)
    从Google Earth 中下载三维模型
    Hadoop安装所遇问题及解决方法
    智慧家居体系结构
    .Net 数据库(SqlServer2008)的备份、还原
  • 原文地址:https://www.cnblogs.com/agenthtb/p/7689062.html
Copyright © 2011-2022 走看看