题目大意
是给出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;
}
本文介绍了一种算法,用于从给定的整点集中找出一个包含所有点的最大三角形,其面积不超过给定值的四倍。通过遍历点集并逐步扩大三角形面积来实现。文中提供了一种O(n²)的基本方法及一种基于凸包的优化方案。

622

被折叠的 条评论
为什么被折叠?



