zoukankan      html  css  js  c++  java
  • POJ

    Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points.

    Input

    The input consists of several test cases. The first line of each test case contains an integer n, indicating the number of points on the plane. Each of the following n lines contains two integer xi and yi, indicating the ith points. The last line of the input is an integer −1, indicating the end of input, which should not be processed. You may assume that 1 <= n <= 50000 and −10 4 <= xi, yi <= 10 4 for all i = 1 . . . n.

    Output

    For each test case, print a line containing the maximum area, which contains two digits after the decimal point. You may assume that there is always an answer which is greater than zero.

    Sample Input

    3
    3 4
    2 6
    2 7
    5
    2 6
    3 9
    2 0
    8 0
    6 5
    -1

    Sample Output

    0.50
    27.00

    题意:在二维平面上面找三个点构成三角形,使得其面积最大。

    思路1:枚举三角形的一条边,然后通过旋转卡壳找最远的点; 自己想的,而且AC了。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define ll long long
    #define RC rotating_calipers
    using namespace std;
    const int maxn=100010;
    struct point{
        double x,y;
        point(double x=0,double y=0):x(x),y(y){}
        bool operator < (const point &c) const { return x<c.x||(x==c.x&&y<c.y);}
        point operator - (const point &c) const { return point(x-c.x,y-c.y);}
        double operator * (const point &c) const { return x*c.y-y*c.x; }
        double operator | (const point &c) const { return (x-c.x)*(x-c.x)+(y-c.y)*(y-c.y); }
    };
    double det(point A,point B){ return A.x*B.y-A.y*B.x;}
    double det(point O,point A,point B){ return det(A-O,B-O);}
    point a[maxn],ch[maxn];
    void convexhull(int n,int &top)
    {
        sort(a+1,a+n+1); top=0;
        for(int i=1;i<=n;i++){
            while(top>1&&det(ch[top-1],ch[top],a[i])<=0) top--;
            ch[++top]=a[i];
        }
        int ttop=top;
        for(int i=n-1;i>=1;i--){
            while(top>ttop&&det(ch[top-1],ch[top],a[i])<=0) top--;
            ch[++top]=a[i];
        }
    }
    double rotating_calipers(point p[],int top)
    {
        top--;
        double ans=0; int now;
        rep(i,1,top-2){
            int now=i+2;
            rep(j,i+1,top-1){
               while(now<=top&&fabs(det(p[i],p[j],p[now]))<fabs(det(p[i],p[j],p[now+1]))){
                  now++;
               }
               ans=max(ans,fabs(det(p[i],p[j],p[now])));
            }
        }
        return ans;
    }
    int main()
    {
        int N;
        while(~scanf("%d",&N)&&N!=-1){
            for(int i=1;i<=N;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
            int top; convexhull(N,top);
            double ans=RC(ch,top);
            printf("%.2f
    ",0.5*ans);
        }
        return 0;
    }

    思路2:枚举三角形的一个点,然后通过旋转卡壳找最远的边。别人的代码,AC了,但是拿去做CF的时候WA36了。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define ll long long
    #define RC rotating_calipers
    using namespace std;
    const int maxn=100010;
    struct point{
        double x,y;
        point(double x=0,double y=0):x(x),y(y){}
        bool operator < (const point &c) const { return x<c.x||(x==c.x&&y<c.y);}
        point operator - (const point &c) const { return point(x-c.x,y-c.y);}
    };
    double det(point A,point B){ return A.x*B.y-A.y*B.x;}
    double det(point O,point A,point B){ return det(A-O,B-O);}
    point a[maxn],ch[maxn];
    void convexhull(int n,int &top)
    {
        sort(a+1,a+n+1); top=0;
        for(int i=1;i<=n;i++){
            while(top>1&&det(ch[top-1],ch[top],a[i])<=0) top--;
            ch[++top]=a[i];
        }
        int ttop=top;
        for(int i=n-1;i>=1;i--){
            while(top>ttop&&det(ch[top-1],ch[top],a[i])<=0) top--;
            ch[++top]=a[i];
        }
    }
    double rotating_calipers(point p[],int top)
    {
        double ans=0; int now1=1,now2=2;
        rep(i,1,top){
            while(fabs(det(p[i],p[now1],p[now2]))<fabs(det(p[i],p[now1],p[now2+1]))){
                now2++;if(now2==top+1) now2=1;
            }//利用其是单峰函数
    while(fabs(det(p[i],p[now1],p[now2]))<fabs(det(p[i],p[now1+1],p[now2]))){ now1++;if(now1==top+1) now1=1; } ans=max(ans,fabs(det(p[i],p[now1],p[now2]))); } return ans; } int main() { int N; while(~scanf("%d",&N)&&N!=-1){ for(int i=1;i<=N;i++) scanf("%lf%lf",&a[i].x,&a[i].y); int top; convexhull(N,top); double ans=RC(ch,top-1); printf("%.2f ",0.5*ans); } return 0; }
  • 相关阅读:
    配置WepApi默认支持JSON数据格式的返回 人工智能
    让人HOLD不住的新闻,Windows8将何去何从?Windows8的开发何去何从? 人工智能
    MVC开发的小问题及解决方案记录 人工智能
    在埋头写程序学技术的同时,有没有想到你们的老板和上司在搞什么? 人工智能
    Func与Action, delegate, event, var, dynamic, 匿名方法,lambda, 大量的关键都使用相同功能,大大增加C#复杂性 人工智能
    畅想(2)计算机发展与教育的关系 人工智能
    函数式编程学习之路(二) 人工智能
    C++关键字(1)——const
    怎样在阻塞模式下设置recv()函数的阻塞时间
    队列
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9620486.html
Copyright © 2011-2022 走看看