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;
    }
    
  • 相关阅读:
    jsp页面数据分页模仿百度分页效果
    java EL表达式
    服务器端javascript——Rhino和Node
    HBase协处理器
    Hbase 计数器
    javascript正则表达式(二)——方法
    javascript正则表达式(一)——语法
    javascript模块化
    使用sqoop工具从oracle导入数据
    HBASE API操作问题总结
  • 原文地址:https://www.cnblogs.com/juechen/p/5255903.html
Copyright © 2011-2022 走看看