zoukankan      html  css  js  c++  java
  • Bzoj1185 [HNOI2007]最小矩形覆盖

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
    Submit: 1653  Solved: 745
    [Submit][Status][Discuss]

    Description

     

    Input

     

    Output

     

    Sample Input

     

    Sample Output

     

    HINT

     

    Source

    数学问题 计算几何 旋转卡壳

    按顺序枚举凸包上每一条边为底边,旋转卡壳找出此时的矩形的顶点、最左点和最右点,花式计算出边长,求面积,记录面积最小值和对应的解。

    式子都能看懂,但不看题解就是写不出来,沮丧。

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 using namespace std;
      9 const int INF=0x3f3f3f3f;
     10 const double eps=1e-8;
     11 const int mxn=100010;
     12 int read(){
     13     int x=0,f=1;char ch=getchar();
     14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 inline int DT(double x){
     19     if(abs(x)<eps)return 0;
     20     else return x<0?-1:1;
     21 }
     22 struct point{
     23     double x,y;
     24     point operator + (point b){return (point){x+b.x,y+b.y};}
     25     point operator - (point b){return (point){x-b.x,y-b.y};}
     26     point operator * (double v){return (point){x*v,y*v};}
     27     point operator / (double v){return (point){x/v,y/v};}
     28     bool operator < (point b)const{
     29         return x<b.x || (x==b.x && y<b.y);
     30     }
     31 }a[mxn],p[mxn],ans[5];
     32 typedef point Vector;
     33 double dot (point a,point b){return a.x*b.x+a.y*b.y;}
     34 double Cross(point a,point b){
     35     return a.x*b.y-a.y*b.x;
     36 }
     37 double dist(point a,point b){
     38     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     39 }
     40 double Len(point a){
     41     return sqrt((a.x*a.x)+(a.y*a.y));
     42 }
     43 double DLC(point p,point a,point b){
     44     Vector v1=p-a,v2=b-a;
     45     return fabs(Cross(v1,v2)/Len(v2));
     46 }
     47 int n;
     48 double ANS=0;
     49 int st[mxn],top=0,t2=0;
     50 void Andrew(){
     51     sort(p+1,p+n+1);
     52     for(int i=1;i<=n;i++){
     53         while(top>1 && Cross(p[st[top]]-p[st[top-1]],p[i]-p[st[top-1]])<=0)top--;
     54         st[++top]=i;
     55     }
     56     t2=top;
     57     for(int i=n-1;i;i--){
     58         while(t2>top && Cross(p[st[t2]]-p[st[t2-1]],p[i]-p[st[t2-1]])<=0)t2--;
     59         st[++t2]=i;
     60     }
     61     if(n>1)t2--;
     62     n=t2;
     63     for(int i=1;i<=n;i++){
     64         a[i]=p[st[i]];
     65     }
     66     return;
     67 }
     68 void solve(){
     69     ANS=(double)INF;
     70     a[n+1]=a[1];
     71     int l=1,r=1,tmp=1;
     72     double H,D,L,R;
     73     for(int i=1;i<=n;i++){
     74         while(DT(DLC(a[tmp],a[i],a[i+1])-DLC(a[tmp+1],a[i],a[i+1]))<=0)tmp=tmp%n+1;//顶部 
     75         while(DT(dot(a[i+1]-a[i],a[l]-a[i])-dot(a[i+1]-a[i],a[l+1]-a[i]))<=0)l=l%n+1;//左边 
     76         if(i==1)r=tmp;
     77         while(DT(dot(a[i+1]-a[i],a[r]-a[i])-dot(a[i+1]-a[i],a[r+1]-a[i]))>=0)r=r%n+1;//右边 
     78 //      printf("i:%d l:%d tmp:%d r:%d
    ",i,l,tmp,r);
     79         L=dist(a[i+1],a[i]);
     80 //      H=fabs(Cross(a[tmp]-a[i],a[i+1]-a[i]))/L;//
     81         H=DLC(a[tmp],a[i],a[i+1]);
     82         D=fabs(dot(a[i+1]-a[i],a[l]-a[i])/L)+fabs(dot(a[i+1]-a[i],a[r]-a[i])/L);//底边长 
     83         R=H*D;
     84 //      printf("L:%.3f H:%.3f D:%.3f R:%.3f
    ",L,H,D,R);
     85         if(R<ANS){//更新答案 
     86             ANS=R;
     87             Vector v=(a[i+1]-a[i])/L;//单位长度
     88             Vector u=(point){-v.y,v.x};//v逆时针转90度 
     89             ans[1]=a[i]+v*dot(a[r]-a[i],v);
     90             ans[2]=a[i]+v*dot(a[l]-a[i],v);
     91             ans[3]=ans[2]+u*H;
     92             ans[4]=ans[1]+u*H;
     93         }
     94     }
     95     return;
     96 }
     97 int main(){
     98 //  freopen("in.txt","r",stdin);
     99     int i,j;
    100     scanf("%d",&n);
    101     for(i=1;i<=n;i++){
    102         scanf("%lf%lf",&p[i].x,&p[i].y);
    103     }
    104     Andrew();
    105 /*  printf("n:%d
    ",n);
    106     for(i=1;i<=n;i++){
    107         printf("%.3f  %.3f
    ",a[i].x,a[i].y);
    108     }*/
    109     solve();
    110     int pos=1;
    111     for(i=1;i<=4;i++){
    112         if(ans[i].y<eps)ans[i].y=0;
    113         if(ans[i].x<eps)ans[i].x=0;
    114         if(ans[i].y<ans[pos].y || (ans[i].y==ans[pos].y && ans[i].x<ans[pos].x))pos=i;
    115     }
    116     if(ANS<eps)ANS=0;
    117     printf("%.5f
    ",ANS);
    118     for(i=pos;i<=4;i++)
    119         printf("%.5f %.5f
    ",ans[i].x,ans[i].y);
    120     for(i=1;i<pos;i++)
    121         printf("%.5f %.5f
    ",ans[i].x,ans[i].y);
    122     return 0;
    123 }
  • 相关阅读:
    ‘Host’ is not allowed to connect to this mysql server
    centos7安装mysql
    further configuration avilable 不见了
    Dynamic Web Module 3.0 requires Java 1.6 or newer
    hadoop启动 datanode的live node为0
    ssh远程访问失败 Centos7
    Linux 下的各种环境安装
    Centos7 安装 python2.7
    安装scala
    Centos7 安装 jdk 1.8
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6686551.html
Copyright © 2011-2022 走看看