• 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;
    }
    
  • 相关阅读:
    Java8新特性(一)_interface中的static方法和default方法
    从ELK到EFK演进
    使用Maven构建多模块项目
    maven 把本地jar包打进本地仓库
    在基于acpi的linux系统上如何检查当前系统是否支持深度睡眠?
    linux内核中#if IS_ENABLED(CONFIG_XXX)与#ifdef CONFIG_XXX的区别
    linux内核睡眠状态解析
    如何在linux中测试i2c slave模式驱动的功能?
    insmod内核模块时提示"unknown symbol ..."如何处理?
    insmod某个内核模块时提示“Failed to find the folder holding the modules”如何处理?
  • 原文地址:https://www.cnblogs.com/juechen/p/5255903.html
Copyright © 2020-2023  润新知