nyoj952最大四边形 思路+代码

最大四边形

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
平面坐标上有n个点,你知道能组成四边形中面积最大的是多少吗?
输入
有多组测试数据
第一行整数n,表示有n个点,( 4<=n<=300 )
然后n行,每行x,y表示点的坐标。(没有重复的点)
输出
最大四边形的面积.(保留六位小数)
样例输入
5
0 0
0 4
4 0
4 4
2 3
样例输出
16.000000
上传者

TC_常红立



思路:

这道题目技巧很巧妙,利用了叉乘的性质。首先任取两个点作为分界线,在分界线两边分别取两个点与分界线组成有一条公共边的两个三角形,枚举所有可能性,求出两个三角形的和最大即为最大四边形面积。求Sabc=ac×ab*0.5(叉乘意义)。

#include<bits/stdc++.h>
using namespace std;
struct point
{
    double x,y;
}p[305],s[305];
int cmp(point a,point b)
{
    if(a.x==b.x)
        return a.y<b.y;
   else  return a.x<b.x;
}
double maxx(double a,double b)
{
    if(a>=b) return a;
    else return b;
}

double judge2(point a, point b, point c)//ab×ac叉乘
{
    double bax = b.x-a.x;
    double bay = b.y-a.y;
    double cax = c.x-a.x;
    double cay = c.y-a.y;
    return (bax*cay - bay*cax )*0.5;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(s,0,sizeof(s));
        memset(p,0,sizeof(p));
        for(int i=0;i<n;i++)
            scanf("%lf %lf",&p[i].x,&p[i].y);

        double s1=0,s2=0,S=0;
        double sm1=0,sm2=0;
        double flag;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(j==i) continue;
                s1=0,s2=0;
                for(int k=0;k<n;k++)
                {
                    if(k!=i&&k!=j)//分界线为ij

                    {
                        flag=judge2(p[k],p[i],p[j]);
                      // cout<<flag<<endl;
                        if(flag>=0)//通过叉乘正负来判断点在分界线那边
                        {
                            sm1=fabs(flag);
                          //  cout<<sm1<<endl;
                            if(s1<sm1) s1=sm1;
                        }
                        else
                        {
                            sm2=fabs(flag);
                            //cout<<sm2<<endl;
                            if(s2<sm2) s2=sm2;
                        }
                       // cout<<s1<<" "<<s2<<endl;
                       // cout<<k<<" "<<i<<" "<<j<<endl;
                    }
                }
                if(s1&&s2)
                S=maxx(S,s1+s2) ;//对每一条分界线求出最大面积然后对比直到求出遍历所有点的最大四边形面积
            }
        }
        //cout<<s1<<" "<<s2<<endl;
        //S=s1+s2;

        printf("%.6lf\n",S);
    }
    return 0;
}





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值