Cf #358 (Div. 2) E Alyona and Triangles (682E)

本文介绍了一种算法,用于从给定的整点集中找出一个包含所有点的最大三角形,其面积不超过给定值的四倍。通过遍历点集并逐步扩大三角形面积来实现。文中提供了一种O(n²)的基本方法及一种基于凸包的优化方案。
  • 题目大意
    是给出n个整点,任意三个点组成三角形的面积不超过s,求一个面积不超过4s的大三角形,该三角形包含这n个整点,且三角形的每个点的坐标为整数。

  • 找到其中面积最大的三角形,将其扩展四倍(以每条边为对角线做平行四边形)形成一个大三角形,即为所求

  • 至于怎么找面积最大的三角形,有几种不同的做法,最基本的是找一个小三角形,一遍一遍的遍历,更新这个三角形的顶点,使其面积不断增大,直到无法扩大为止。虽然是0(n2),但由于遍历一遍后三角形已经比较大了,所以这个方法的速度还是很快的。

  • 有大神的做法是找这些点的外围凸包,在这个凸包上,将3个点按同一方向遍历找三角形,据说是o(nlogn )

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define INF 0x3fffffff
using namespace std;
typedef long long ll;
const int MAX_N = 5000+10;

ll x[MAX_N];
ll y[MAX_N];
int n;
ll s;
int a,b,c;

ll ar(int a,int b,int c)
{
    return abs((x[b]-x[a])*(y[c]-y[a])-(y[b]-y[a])*(x[c]-x[a]));
}

void finds()
{
    a=1;
    b=2;
    c=3;
    int flag=0;
    while(1)
    {
        flag=0;
        for(int i=1;i<=n;i++)
        {
            if(ar(i,b,c)>ar(a,b,c))
                a=i,flag=1;
            if(ar(a,i,c)>ar(a,b,c))
                b=i,flag=1;
            if(ar(a,b,i)>ar(a,b,c))
                c=i,flag=1;
        }

        if(flag == 0)
            break;
    }

}


int main()
{
    while(scanf("%d%I64d",&n,&s)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            cin>>x[i]>>y[i];
        }
        finds();

        cout<<x[c]-x[a]+x[b]<<" "<<y[b]-y[a]+y[c]<<endl;
        cout<<x[a]-x[c]+x[b]<<" "<<y[b]-y[c]+y[a]<<endl;
        cout<<x[c]-x[b]+x[a]<<" "<<y[c]-y[b]+y[a]<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值