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;
    }
    
  • 相关阅读:
    delphi中屏蔽浏览器控件右键菜单
    书目:一些
    数据库ADONETDataAdapter对象参考
    数据库ADONET排序、搜索和筛选
    易语言数据类型及其长度
    易语言数据类型的初始值
    数据库ADONET使用DataAdapter对象
    ADONET使用DataSet处理脱机数据
    数据库ADONETOleDbParameter对象参考
    在项目中添加新数据集
  • 原文地址:https://www.cnblogs.com/juechen/p/5255903.html
Copyright © 2011-2022 走看看