• bzoj 1185 旋转卡壳 最小矩形覆盖


    题目大意 就是求一个最小矩形覆盖,逆时针输出其上面的点

    这里可以看出,那个最小的矩形覆盖必然有一条边经过其中凸包上的两个点,另外三条边必然至少经过其中一个点,而这样的每一个点逆时针走一遍都满足单调性

    所以可以利用旋转卡壳的思想找到这样的三个点

    以每一条边作为基础,循环n次得到n个这样的矩形,找到其中面积最小的即可

    然后自己画画图,作出矩形对应的两条边的单位向量,那么这四个点就非常好求了

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 using namespace std;
      7 #define N 50010
      8 #define eps 1e-9
      9 const double PI = acos(-1.0);
     10 int n , top;
     11 
     12 int dcmp(double x)
     13 {
     14     if(fabs(x)<eps) return 0;
     15     return x<0?-1:1;
     16 }
     17 
     18 struct Point{
     19     double x , y;
     20     Point(double x=0 , double y=0):x(x),y(y){}
     21     void input(){scanf("%lf%lf" , &x , &y);}
     22     void output(){printf("%.5f %.5f
    " , x , y);}
     23     bool operator<(const Point &m)const{
     24         return x<m.x||(x==m.x&&y<m.y);
     25     }
     26 }po[N] , rec[N] , p[4];
     27 
     28 typedef Point Vector;
     29 
     30 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
     31 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
     32 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
     33 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
     34 double operator*(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
     35 
     36 double Dot(Vector a , Vector b){return a.x*b.x+a.y*b.y;}
     37 double Len(Vector a){return sqrt(Dot(a,a));}
     38 int Polxy()
     39 {
     40     sort(po , po+n);
     41     rec[0]=po[0] , rec[1]=po[1];
     42     top=2;
     43     for(int i=2 ; i<n ; i++){
     44         while(top>=2&&(rec[top-1]-rec[top-2])*(po[i]-rec[top-2])<=0)
     45             top--;
     46         rec[top++] = po[i];
     47     }
     48     int tmp=top;
     49     for(int i=n-2 ; i>=0 ; i--){
     50         while(top>=tmp&&(rec[top-1]-rec[top-2])*(po[i]-rec[top-2])<=0)
     51             top--;
     52         rec[top++] = po[i];
     53     }
     54     top--;
     55     return top;
     56 }
     57 
     58 Vector Normal(Vector a)
     59 {
     60     double l = Len(a);
     61     return Vector(-a.y/l , a.x/l);
     62 }
     63 
     64 double calCalip()
     65 {
     66   //  for(int i=0 ; i<top ; i++) rec[i].output();
     67     Point ch[2];
     68     ch[0] = rec[0] , ch[1] = rec[1];
     69     int i1=0 , i2=0 , i3=0;
     70     double maxn = 1e18;
     71     ch[0] = rec[0] , ch[1] = rec[1];
     72     while(dcmp(fabs((rec[(i1+1)%top]-ch[0])*(ch[1]-ch[0]))-fabs((rec[i1]-ch[0])*(ch[1]-ch[0])))>=0) i1=(i1+1)%top;
     73     while(dcmp(Dot(rec[(i2+1)%top]-ch[0] , ch[1]-ch[0])-Dot(rec[i2]-ch[0] , ch[1]-ch[0]))>=0) i2=(i2+1)%top;
     74     while(dcmp(Dot(rec[(i3-1+top)%top]-ch[1] , ch[0]-ch[1])-Dot(rec[i3]-ch[1] , ch[0]-ch[1]))>=0) i3=(i3-1+top)%top;
     75     for(int i=0 ; i<top ; i++){
     76         ch[0] = rec[i] , ch[1] = rec[(i+1)%top];
     77         while(dcmp(fabs((rec[(i1+1)%top]-ch[0])*(ch[1]-ch[0]))-fabs((rec[i1]-ch[0])*(ch[1]-ch[0])))>=0) i1=(i1+1)%top;
     78         while(dcmp(Dot(rec[(i2+1)%top]-ch[0] , ch[1]-ch[0])-Dot(rec[i2]-ch[0] , ch[1]-ch[0]))>=0) i2=(i2+1)%top;
     79         while(dcmp(Dot(rec[(i3+1)%top]-ch[1] , ch[0]-ch[1])-Dot(rec[i3]-ch[1] , ch[0]-ch[1]))>=0) i3=(i3+1)%top;
     80         double l = Len(ch[1]-ch[0]);
     81         double h = fabs((rec[i1]-ch[0])*(ch[1]-ch[0]))/l;
     82         double len1 = Dot(rec[i2]-ch[1] , ch[1]-ch[0])/l; //右侧长度
     83         double len2 = Dot(rec[i3]-ch[0] , ch[0]-ch[1])/l; //左侧长度
     84         double suml = l+len1+len2;
     85        // cout<<i<<" "<<l<<" "<<h<<" "<<len1<<" "<<len2<<" "<<suml*h<<endl;
     86         if(dcmp(suml*h-maxn)<0){
     87             Vector unit1 = (ch[1]-ch[0])/l;
     88             Vector unit2 = Normal(unit1);
     89             maxn = suml*h;
     90             p[0] = ch[1]+unit1*len1;
     91             p[1] = p[0]+unit2*h;
     92             p[2] = p[1]-unit1*suml;
     93             p[3] = p[2]-unit2*h;
     94         }
     95     }
     96     return maxn;
     97 }
     98 
     99 int main()
    100 {
    101    // freopen("in.txt" , "r" , stdin);
    102     while(scanf("%d" , &n)!=EOF)
    103     {
    104         for(int i=0 ; i<n ; i++) po[i].input();
    105         Polxy();
    106         double ret = calCalip();
    107         printf("%.5f
    " , ret);
    108         int st = 0;
    109         for(int i=1 ; i<4 ; i++){
    110             if(p[i].y<p[st].y || (p[i].y==p[st].y&&p[i].x<p[st].x)) st = i;
    111         }
    112         for(int i=0;i<4;i++){
    113             p[st].output();
    114             st = (st+1)%4;
    115         }
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    Candy leetcode java
    Trapping Rain Water leetcode java
    Best Time to Buy and Sell Stock III leetcode java
    Best Time to Buy and Sell Stock II leetcode java
    Best Time to Buy and Sell Stock leetcode java
    Maximum Subarray leetcode java
    Word Break II leetcode java
    Word Break leetcode java
    Anagrams leetcode java
    Clone Graph leetcode java(DFS and BFS 基础)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4638694.html
Copyright © 2020-2023  润新知