码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1069 SCOI 2007 最大土地面积 凸包+旋转卡壳

时间:2015-01-22 09:29:32      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:bzoj   计算几何   凸包   旋转卡壳   scoi 2007   

题目大意:给出平面上的一些点,求其中四个点的最大四边形的面积。


思路:简单yy一下发现这些点肯定都在凸包上,先求个凸包。然后直接暴力肯定是不行的,我们需要一个O(n^2)的做法,比较简单的想法是枚举最后要求的四边形的一条对线,那么这个四边形就被分割成了两个三角形,剩下两个点与这条线组成的三角形的面积和就是答案。

按照旋转卡壳的思想不难发现,这两个点都是单调的。所以枚举对角线然后扫n圈就可以了。


CODE:

#define _CRT_SECURE_NO_DEPRECATE

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define MAX 10010
#define INF 1e15
using namespace std;

struct Point{
	double x,y;

	Point(double _,double __):x(_),y(__) {}
	Point() {}
	bool operator <(const Point &a)const {
		return x == a.x ? (y < a.y) : (x < a.x);
	}
	Point operator -(const Point &a)const {
		return Point(x - a.x,y - a.y);
	}
	void Read() {
		scanf("%lf%lf",&x,&y);
	}
}point[MAX];

inline double Cross(const Point &p1,const Point &p2)
{
	return p1.x * p2.y - p1.y * p2.x;
}

inline double Calc(const Point &p1,const Point &p2)
{
	return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

int points,top;
Point stack[MAX];
int lines;

inline void Add(const Point &a,int bottom)
{
	while(top != bottom && Cross(a - stack[top - 1],stack[top] - stack[top - 1]) >= 0)
		--top;
	stack[++top] = a;
}

double RotatingCaliper()
{
	double re = .0;
	for(int i = 0; i < top; ++i) {
		int p1 = 1,p2 = 1;
		for(int j = i + 1; j < top; ++j) {
			while(Cross(stack[p1 + 1] - stack[i],stack[j] - stack[i]) > Cross(stack[p1] - stack[i],stack[j] - stack[i]))
				p1 = (p1 + 1) % top;
			while(Cross(stack[j] - stack[i],stack[p2 + 1] - stack[i]) > Cross(stack[j] - stack[i],stack[p2] - stack[i]))
				p2 = (p2 + 1) % top;
			re = max(re,Cross(stack[p1] - stack[i],stack[j] - stack[i]) + Cross(stack[j] - stack[i],stack[p2] - stack[i]));
		}
	}
	return re / 2;
}

int main()
{
	cin >> points;
	for(int i = 1; i <= points; ++i)
		point[i].Read();
	sort(point + 1,point + points + 1);
	stack[++top] = point[1];
	for(int i = 2; i <= points; ++i)
		Add(point[i],1);
	int temp = top;
	for(int i = points - 1; i >= 1; --i)
		Add(point[i],temp);
	--top;
	stack[0] = stack[top];
	cout << fixed << setprecision(3) << RotatingCaliper() << endl;
	return 0;
}


BZOJ 1069 SCOI 2007 最大土地面积 凸包+旋转卡壳

标签:bzoj   计算几何   凸包   旋转卡壳   scoi 2007   

原文地址:http://blog.csdn.net/jiangyuze831/article/details/43014603

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!