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;
    }
    
  • 相关阅读:
    NIO编程介绍
    伪异步IO
    BIO模型
    Json
    Jquery笔记
    JQuery与Ajax
    jQuery之事件和动画
    JQueryDOM节点操作
    认识Jquery
    javascript之DOM
  • 原文地址:https://www.cnblogs.com/juechen/p/5255903.html
Copyright © 2011-2022 走看看