zoukankan      html  css  js  c++  java
  • HDU 2202 最大三角形(凸包)

    Problem Description
    老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角形拥有的面积最大。
    Eddy对这道题目百思不得其解,想不通用什么方法来解决,因此他找到了聪明的你,请你帮他解决这个题目。
     
    Input
    输入数据包含多组测试用例,每个测试用例的第一行包含一个整数n,表示一共有n个互不相同的点,接下来的n行每行包含2个整数xi,yi,表示平面上第i个点的x与y坐标。你可以认为:3 <= n <= 50000 而且 -10000 <= xi, yi <= 10000.
     
    Output
    对于每一组测试数据,请输出构成的最大的三角形的面积,结果保留两位小数。
    每组输出占一行。
     
    Sample
    Sample Input
    3
    3 4
    2 6
    3 7
    6
    2 6
    3 9
    2 0
    8 0
    6 6
    7 7
     
    
    Sample Output
    1.50
    27.00

    题意:

      求最大的三角形面积。

    思路

      做出凸包,遍历即可,主要是旋转卡壳不会用,恰好后台数据没有那么大N^3没有T。三角形面积可以用两向量叉乘/2求出。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define PI 3.1415926535
    using namespace std;
    struct node
    {
        int x,y;
    };
    node vex[100000];//存入的所有的点
    node stackk[100000];//凸包中所有的点
    int xx,yy;
    bool cmp1(node a,node b)
    {
        if(a.y==b.y)
            return a.x<b.x;
        else
            return a.y<b.y;
    }
    double cross(node a,node b,node c)//计算叉积
    {
        return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
    }
    double dis(node a,node b)//计算距离
    {
        return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
    }
    bool cmp2(node a,node b)//极角排序另一种方法,速度快
    {
        if(atan2(a.y-yy,a.x-xx)!=atan2(b.y-yy,b.x-xx))
            return (atan2(a.y-yy,a.x-xx))<(atan2(b.y-yy,b.x-xx));
        return a.x<b.x;
    }
    bool cmp(node a,node b)//极角排序
    {
        int m=cross(vex[0],a,b);
        if(m>0)
            return 1;
        else if(m==0&&dis(vex[0],a)-dis(vex[0],b)<=0)
            return 1;
        else return 0;
        /*if(m==0)
            return dis(vex[0],a)-dis(vex[0],b)<=0?true:false;
        else
            return m>0?true:false;*/
    }
    int main()
    {
        int t,L;
        while(~scanf("%d",&t))
        {
            int i;
            for(i=0; i<t; i++)
            {
                scanf("%d%d",&vex[i].x,&vex[i].y);
            }
            memset(stackk,0,sizeof(stackk));
            sort(vex,vex+t,cmp1);
            stackk[0]=vex[0];
            xx=stackk[0].x;
            yy=stackk[0].y;
            sort(vex+1,vex+t,cmp2);
            stackk[1]=vex[1];//将凸包中的前两个点存入凸包的结构体中
            int top=1;//最后凸包中拥有点的个数*/
            for(i=2; i<t; i++)
            {
                while(i>=1&&cross(stackk[top-1],stackk[top],vex[i])<0)
                    top--;
                stackk[++top]=vex[i];
            }
           double s=0;//三角形的面积可以由向量叉乘/2
            for(int i = 0; i<=top; i++)
                for(int j = i+1; j<=top; j++)
                    for(int k = j+1; k<=top; k++)
                        s = max(s,cross(stackk[i],stackk[j],stackk[k]));
            printf("%.2lf
    ",s/2.0);
    
        }
    }
  • 相关阅读:
    Android listview 的应用
    Android 创建自定义布局
    Android Dialog
    android ProgressBar
    Lilac Pwn stack4-stack_pivoting Writeup
    CTFHUB Pwn ret2shellcode Writeup
    Lilac Pwn stack3-rop Writeup
    函数调用过程与栈帧结构
    线性回归及Python实现
    Google Kick Start Round A 2020
  • 原文地址:https://www.cnblogs.com/aiguona/p/7249063.html
Copyright © 2011-2022 走看看