zoukankan      html  css  js  c++  java
  • BZOJ 1069 最大土地面积

    Description

    在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大。

    Input

    第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。

    Output

    最大的多边形面积,答案精确到小数点后3位。

    Sample Input

    5
    0 0
    1 0
    1 1
    0 1
    0.5 0.5

    Sample Output

    1.000

    HINT

    数据范围 n<=2000, |x|,|y|<=100000

    旋转卡壳的一道裸题。首先确定一点,面积最大的四个点肯定是在凸包上的。因此,我们可以枚举凸包上的两个点(对角线),另外两个通过与对角线距离单峰性直接维护。(这就叫做旋转卡壳。。。)
    实在听不懂的话看代码,我把计算几何写成了解析几何了。。。

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    #define esp (1e-6)
    #define maxn 2010
    int n,m; double ans;
    
    inline double qua(double a) { return a*a; }
    
    struct NODE
    {
    	double x,y;
    	friend inline bool operator < (NODE a,NODE b) { if (a.x == b.x) return a.y < b.y; return a.x < b.x; }
    	friend inline NODE operator - (NODE a,NODE b) { return (NODE) {a.x - b.x,a.y - b.y}; }
    	friend inline double operator / (NODE a,NODE b) { return a.x*b.y-a.y*b.x; }
    	inline double len() { return sqrt(qua(x)+qua(y)); }
    	inline void read() { scanf("%lf %lf",&x,&y); }
    }pp[maxn],ch[maxn*2];
    struct LINE
    {
    	double a,b,c;
    	inline double dis(NODE p) { return fabs(a*p.x+b*p.y+c)/sqrt(qua(a)+qua(b)); }
    };
    struct SEG
    {
    	NODE a,b;
    	inline LINE extend() { return (LINE) {a.y-b.y,b.x-a.x,b.y*(a.x-b.x)-b.x*(a.y-b.y)}; }
    };
    
    inline void convex()
    {
    	sort(pp + 1,pp + n + 1);
    	for (int i = 1;i <= n;++i)
    	{
    		while (m > 1&&(ch[m]-ch[m-1])/(pp[i]-ch[m-1]) <= 0) --m;
    		ch[++m] = pp[i];
    	}
    	int k = m;
    	for (int i = n - 1;i;--i)
    	{
    		while (m > k&&(ch[m]-ch[m-1])/(pp[i] - ch[m - 1]) <= 0) --m;
    		ch[++m] = pp[i];
    	}
    	if (n > 1) m--;
    }
    
    inline void jam()
    {
    	for (int i = 1;i <= m;++i) ch[i+m] = ch[i];
    	int p1,p2,p3,p4; LINE l;
    	for (p1 = 1;p1 <= m;++p1)
    	{
    		p2 = p1 + 1;
    		p3 = p2 + 1;
    		p4 = p3 + 1;
    		for (;p3 < p1 + m - 1;++p3)
    		{
    			l = ((SEG) { ch[p1],ch[p3] }).extend();
    			while (p2 < p3 && l.dis(ch[p2]) < l.dis(ch[p2 + 1])) ++p2;
    			while (p4 < p1 + m && l.dis(ch[p4]) < l.dis(ch[p4 + 1])) ++p4;
    			ans = max(ans,(l.dis(ch[p2])+l.dis(ch[p4]))*(ch[p1] - ch[p3]).len()/2);
    		}
    	}
    }
    
    int main()
    {
    	freopen("1069.in","r",stdin);
    	freopen("1069.out","w",stdout);
    	scanf("%d",&n);
    	for (int i = 1;i <= n;++i) pp[i].read();
    	convex();
    	jam();
    	printf("%.3lf",ans);
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    Lua build and install
    tomcat 配置的另外一种方法
    debian vsftp
    git(1)
    jd-gui安装
    debian crash log查看
    ros学习笔记
    51nod 1138 连续整数的和(数学公式)
    51nod 1428 活动安排问题(优先队列)
    Codeforces Round #347 (Div. 2) (练习)
  • 原文地址:https://www.cnblogs.com/mmlz/p/4297989.html
Copyright © 2011-2022 走看看