land
题目描述
dog终于有了一块领地,但是现在可怜的dog面临着lxy的入侵,于是他决定在自己的领地设置炮楼来保卫自己免受QJ。现在dog找到它可以在领地上设置炮楼的N个地点。但是留给dog的时间不多了,dog决定赶快建4个炮楼。而现在的问题是dog希望这4个炮楼的防守区域最大。而4个炮楼的防守区域就是这4个炮楼的多边形的面积。Dog马上找到了你,请你帮助他,而你不忍心让dog惨遭蹂躏,那么请告诉dog他的防守区域最大为多少。(保证最终得到的防守区域是凸四边形)
输出输出
输入文件:
第1行1个数n,表示可能修建炮楼的位置。接下来n行,每行2个数x,y,表示可能的炮楼的位置。(不考虑地球曲面的影响,默认为dog的领地是块平面,然后建立直角坐标系,给出的就是直角坐标系上的位置)。输出文件:
dog他的防守区域最大为多少。精确到小数点后3位。样例
输入
50 01 01 10 10.5 0.5
输出
1
说明
数据范围
100%的数据中,n<=2000,|x|,|y|<=100000.
50%的数据中,n<=1000, |x|,|y|<=10000. 30%的数据中,n<=50, |x|,|y|<=100.
思路
给出点集S,要求从S中选出4个点,使得这四个点组成的四边形面积最大(S<=2000)
如果最终得到的是凸四边形,题目就好做得多了。 对于这一题数据较小,O(n^2)的复杂度是能够AC的。优美的暴力
- 对于第一个点,找出离它最远的点,连接这两个点成一个线段
- 枚举每一个点,分别找出线段两边距离线段最远的点
- 用叉乘或者分割成两个三角形计算四边形的面积
- 与最大值比较,更新最大值
- 对于第二个点,第三个······重复操作
代码
#include#include #include #define MAXX 2000+5using namespace std;int n,maxnum,maxup,maxunder;double x[MAXX],y[MAXX],k,b;inline void search(int p){ double maxn=-1000; for(int i=1;i<=n;i++){ if(i==p) continue; if(maxn =y[i]) continue; if(maxn<(abs(k*x[i]-y[i]+b)/sqrt(k*k+1))){ maxn=(abs(k*x[i]-y[i]+b)/sqrt(k*k+1)); maxup=i; } }}inline void rununder(int p){ double maxn=-1000; for(int i=1;i<=n;i++){ if(i==p) continue; if(x[i]*k+b<=y[i]) continue; if(maxn<(abs(k*x[i]-y[i]+b)/sqrt(k*k+1))){ maxn=(abs(k*x[i]-y[i]+b)/sqrt(k*k+1)); maxunder=i; } }}inline double get_s(int i){ double s=0; s+=x[i]*y[maxup]-x[maxup]*y[i]; s+=x[maxup]*y[maxnum]-x[maxnum]*y[maxup]; s+=x[maxnum]*y[maxunder]-x[maxunder]*y[maxnum]; s+=x[maxunder]*y[i]-x[i]*y[maxunder]; s*=0.5; s=abs(s); return s;}int main(){ freopen("Land.in","r",stdin); freopen("Land.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); double ans=-1; for(int i=1;i<=n;i++){ search(i); fangcheng(i); runup(i); rununder(i); ans=max(get_s(i),ans); } printf("%.3lf",ans); return 0;}