bzoj1069: [SCOI2007]最大土地面积

题目

  http://www.lydsy.com/JudgeOnline/problem.php?id=1069

题解

  我的第一道旋转卡壳。一开始WA,但就是查不出错来,最后直接套用了我以前的模板(求凸包部分),A了。

  其实很水,就是先求一下凸包,然后枚举矩形的对角线,另外两个点旋转卡壳一下就行了。

代码

//凸包、旋转卡壳 
#include <cstdio>
#include <algorithm>
#include <cmath>
#define eps 10e-7
#define maxn 3000
using namespace std;
struct vec
{
	double x, y;
	double operator*(vec v){return x*v.y-v.x*y;}
	vec operator-(vec v){return (vec){x-v.x,y-v.y};}
}p[maxn], s[maxn];
int N, top, next[maxn];
double S;
bool operator<(vec v1, vec v2)
{
	v1=v1-s[1],v2=v2-s[1];
	return v1*v2==0?v1.x*v1.x+v1.y*v1.y<v2.x*v2.x+v2.y*v2.y:v1*v2>0;
}
void graham()
{
	int i, j;
	vec v1, v2, t;
	for(j=1,i=2;i<=N;i++)
		if(p[i].y<p[j].y or p[i].y==p[j].y and p[i].x<p[j].x)j=i;
	t=p[j],p[j]=p[1],p[1]=t;
	s[top=1]=t;
	sort(p+2,p+N+1);
	for(i=2;i<=N;i++)
	{
		while(top>1 and (p[i]-s[top])*(s[top]-s[top-1])>-eps)top--;
		s[++top]=p[i];
	}
}
double area(vec p1, vec p2, vec p3)
{return abs((p2-p1)*(p3-p1))/2;}
void qiake()
{
	int a, b, p, q, i;
	for(i=1;i<top;i++)next[i]=i+1;next[top]=1;
	for(a=1;a<=top-3;a++)
	{
		p=a+1,q=a+3;
		for(b=a+2;b<=top;b++)
		{
			while(area(s[a],s[b],s[next[p]])>area(s[a],s[b],s[p]))p=next[p];
			while(area(s[a],s[b],s[next[q]])>area(s[a],s[b],s[q]))q=next[q];
			S=max(S,area(s[a],s[b],s[p])+area(s[a],s[b],s[q]));
		}
	}
}
int main()
{
	int i;
	scanf("%d",&N);
	for(i=1;i<=N;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
	graham();
	qiake();
	printf("%.3lf\n",S);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值