zoukankan      html  css  js  c++  java
  • Smallest Bounding Rectangle

    Smallest Bounding Rectangle

    Given the Cartesian coordinates of n(>0)2-dimensional points, write a program that computes the area of their smallest bounding rectangle (smallest rectangle containing all the given points).

    Input

    The input le may contain multiple test cases. Each test case begins with a line containing a positive
    integer n(<1001) indicating the number of points in this test case. Then follows n lines each containing
    two real numbers giving respectively the x - and y
    -coordinates of a point. The input terminates with a
    test case containing a value 0 for n which must not be processed.

    Output

    For each test case in the input print a line containing the area of the smallest bounding rectangle
    rounded to the 4th digit after the decimal point.

    Sample Input

    3
    -3.000 5.000
    7.000 9.000
    17.000 5.000
    4
    10.000 10.000
    10.000 20.000
    20.000 20.000
    20.000 10.000
    0

    Sample Output

    80.0000
    100.0000

    最小外接矩形,不会简单的方法,只能将所给点构成凸包,然后枚举凸包上相邻的两点与x轴的夹角作为矩形的倾斜角c,然后求出沿倾斜角c的方向上的凸包映射的长度和垂直倾斜角c的方向上的映射长度为矩形的长和宽.

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    #include <queue>
    #include <stack>
    #include <set>
    #include <vector>
    #include <map>
    #include <algorithm>
    #define LL long long
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    
    const int Max = 1011;
    
    const double eps = 1e-8;
    
    const double Pi = acos(-1.0);
    
    int sgn(double x)//精度处理
    {
        if(fabs(x)<eps)
        {
            return 0;
        }
        if(x<0)
        {
            return -1;
        }
        else
        {
            return  1;
        }
    }
    
    struct Point
    {
        double x,y;
        Point() {};
        Point(double _x,double _y)
        {
            x=_x;
            y=_y;
        }
        Point operator - (const Point &b)const
        {
            return Point(x-b.x,y-b.y);
        }
        double operator ^ (const Point &b)const
        {
            return x*b.y-y*b.x;
        }
        double operator * (const Point &b)const
        {
            return x*b.x+y*b.y;
        }
        void transXY(double B)
        {
            double tx = x,ty=y;
            x =tx*cos(B)-ty*sin(B);
            y = tx*sin(B)+ty*cos(B);
        }
    } List[Max];
    
    double dist(Point a,Point b)
    {
        return sqrt((a-b)*(a-b));
    }
    int Stack[Max],top;
    
    bool _cmp(Point p1,Point p2)//极角排序
    {
        double tmp = (p1-List[0])^(p2-List[0]);
        if(sgn(tmp)>0)
        {
            return true;
        }
        else if(sgn(tmp)==0 && sgn(dist(p1,List[0])-dist(p2,List[0]))<=0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    void Graham(int n)//凸包
    {
        Point p0;
        int k = 0;
        p0=List[0];
        for(int i=1; i<n; i++)
        {
            if((p0.y>List[i].y)||(p0.y==List[i].y&&p0.x>List[i].x))
            {
                p0=List[i];
                k=i;
            }
        }
        swap(List[k],List[0]);
        sort(List+1,List+n,_cmp);
        if(n==1)
        {
            top=1;
            Stack[0]=0;
            return ;
        }
        if(n==2)
        {
            top= 2 ;
            Stack[0]=0;
            Stack[1]=1;
            return ;
        }
        Stack[0]= 0 ;
        Stack[1]=1;
        top=2;
        for(int i=2; i<n; i++)
        {
            while(top>1&&sgn((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]]))<=0)
                top--;
            Stack[top++]=i;
        }
    }
    
    
    double Get(int n)//计算矩形的最小面积
    {
        double ant,ans ,dis ;
        double x,y;
        double sum = INF;
        Point a;
        for(int i=0; i<n; i++)
        {
            a=List[Stack[(i+1)%n]]-List[Stack[i]];
            ant = atan2(a.y,a.x);//倾斜角
            x = 0;
            y = 0;
            for(int j=0; j<n; j++)
            {
                a=List[Stack[(j+1)%n]]-List[Stack[j]];
                dis =sqrt(a.x*a.x+a.y*a.y);
                ans = atan2(a.y,a.x);
                x+=fabs(dis*sin(ans-ant));//映射总和
                y+=fabs(dis*cos(ans-ant));//映射总和
            }
            sum = min(x*y,sum);
        }
        return sum/4;
    
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)&&n)
        {
            top = 0;
            for(int i=0; i<n; i++)
            {
                scanf("%lf %lf",&List[i].x,&List[i].y);
            }
            Graham(n);
    
            printf("%.4f
    ",Get(top));
        }
    
        return 0;
    }
    
  • 相关阅读:
    Java自学-类和对象 引用
    Java自学-数组 Arrays
    Java自学-数组 二维数组
    Java自学-数组 复制数组
    Java自学-数组 增强型for循环
    IDEA 创建普通的maven+java Project
    git -- 项目开发最常用操作记录
    操作系统-Windows操作系统的线程调度了解这些
    操作系统-CPU调度
    操作系统-线程引入
  • 原文地址:https://www.cnblogs.com/juechen/p/5255903.html
Copyright © 2011-2022 走看看