zoukankan      html  css  js  c++  java
  • [poj] 2079 Triangle || 旋转卡壳

    原题

    给出n个点,求最大面积三角形。


    最大面积三角形一定在凸包上,所以先Graham求凸包。在凸包上旋转卡壳(固定一个定点,旋转一个,在旋转另一个)。
    O(n^2)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 100010
    #define eps 1e-8
    using namespace std;
    int n,m,top,per[N];
    double x,y,area;
    struct point
    {
        double x,y;
        point() : x(0),y(0) {}
        point(double _x,double _y) : x(_x),y(_y) {}
        bool operator < (const point &b) const
    	{
    	    return x<b.x || (x==b.x && y<b.y);
    	}
        point operator + (const point &b) const
    	{
    	    return point(x+b.x,y+b.y);
    	}
        point operator - (const point &b) const
    	{
    	    return point(x-b.x,y-b.y);
    	}
        point operator * (const double &b) const
    	{
    	    return point(x*b,y*b);
    	}
        double operator * (const point &b) const
    	{
    	    return x*b.y-b.x*y;
    	}
        double norm()
    	{
    	    return x*x+y*y;
    	}
    }p[N],q[N];
    
    double ABS(double x) { return x>=0?x:-x; }
    
    int dcmp(double x)
    {
        if (x<=eps && x>=-eps) return 0;
        return x>0?1:-1;
    }
    
    bool cmp(int i,int j)
    {
        int d=(p[i]-p[1])*(p[j]-p[1]);
        if (d!=0) return d<0;
        return (p[i]-p[1]).norm()>(p[j]-p[1]).norm();
    }
    
    void Graham()
    {
        sort(p+1,p+n+1);
        top=0;
        for (int i=1;i<=n;i++)
        {
            while (top>1 && dcmp((q[top]-q[top-1])*(p[i]-q[top-1]))<=0)
                --top;
            q[++top]=p[i];
        }
        int k=top;
        for (int i=n-1;i>=1;i--)
        {
            while (top>k && dcmp((q[top]-q[top-1])*(p[i]-q[top-1]))<=0)
                --top;
            q[++top]=p[i];
        }
        if (n>1) --top;
    }
    
    double rotating()
    {
        if (top<=2) return 0;
        if (top==3) return ABS(((q[2]-q[1])*(q[3]-q[1]))/2.0);
        double ans=0;
        for (int i=1;i<=top;i++)
        {
    	int j=i%top+1;
    	int k=j%top+1;
    	while (dcmp(ABS((q[i]-q[j])*(q[i]-q[k]))-ABS((q[i]-q[j])*(q[i]-q[k%top+1])))<0)
    	    k=k%top+1;
    	while (i!=j && j!=k && i!=k)
    	{
    	    ans=max(ans,ABS(((q[i]-q[j])*(q[i]-q[k]))/2.0));
    	    while(dcmp(ABS((q[i]-q[j])*(q[i]-q[k]))-ABS((q[i]-q[j])*(q[i]-q[k%top+1])))<0)
    		k=k%top+1;
    	    j=j%top+1;
    	}
        }
        return ans;
    }
    
    int main()
    {
        while (~scanf("%d",&n))
        {
    	if (n==-1) break;
    	top=0;
    	for (int i=1;i<=n;i++)
    	    scanf("%lf%lf",&p[i].x,&p[i].y);
    	Graham();
    	area=rotating();
    	printf("%.2lf
    ",area);
        }
        return 0;
    }
    
  • 相关阅读:
    Linux recordmydesktop
    linux music play
    linux config NDK
    linux install wireshark
    Linux config cocos
    45 线程池都有哪些状态?
    44 创建线程池有哪几种方式?
    final 不能修饰抽象类和接口
    43 线程的 run() 和 start() 有什么区别?
    42 notify()和 notifyAll()有什么区别?
  • 原文地址:https://www.cnblogs.com/mrha/p/8168890.html
Copyright © 2011-2022 走看看