【BZOJ3707】圈地 几何

【BZOJ3707】圈地

Description

2维平面上有n个木桩,黄学长有一次圈地的机会并得到圈到的土地,为了体现他的高风亮节,他要使他圈到的土地面积尽量小。圈地需要圈一个至少3个点的多边形,多边形的顶点就是一个木桩,圈得的土地就是这个多边形内部的土地。(因为黄学长非常的神,所以他允许圈出的第n点共线,那样面积算0)

Input

第一行一个整数n,表示木桩个数。
接下来n行,每行2个整数表示一个木桩的坐标,坐标两两不同。

Output

仅一行,表示最小圈得的土地面积,保留2位小数。

Sample Input

3
0 0
0 1
1 0

Sample Output

0.50

HINT

对于100%的数据,n<=1000。

题解:假如我们已经确定了三角形的一条边,那么面积可以表示成 边长*高/2,如果我们将所选的边当做y轴,那么显然第3个点应取|x|最小的点。问题是如何快速确定|x|最小的点。

有一个结论(难想),就是将所有直线按照极角排序(斜率也行),将所有点按y排序(相当于所选的边是x轴),此时所有点距离直线的相对位置是确定的。我们枚举每条直线,当我们从ai,bi枚举到ai+1,bi+1时,只有ai,bi的相对位置发生了改变,其余点的相对位置均不改变。(相对位置指的是以所选直线为y轴后,x的大小关系。这个结论自己画画应该就能理解)

于是我们用桶维护每个点的相对位置即可。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1010;
int n,tot;
int s[maxn],pos[maxn];
double ans;
struct point
{
	double x,y;
	point () {}
	point (double a,double b){x=a,y=b;}
	point operator + (const point &a) const {return point(x+a.x,y+a.y);}
	point operator - (const point &a) const {return point(x-a.x,y-a.y);}
	double operator * (const point &a) const {return x*a.y-y*a.x;}
}p[maxn];
struct line
{
	double k;
	int a,b;
}l[1000000];
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
bool cmpy(point a,point b)
{
	return a.y<b.y;
}
bool cmpk(line a,line b)
{
	return a.k<b.k;
}
void calc(int a,int b,int c)
{
	double S=fabs((p[b]-p[a])*(p[c]-p[a])/2);
	ans=min(ans,S);
}
int main()
{
	n=rd();
	int i,j;
	for(i=1;i<=n;i++)	p[i].x=rd(),p[i].y=rd();
	sort(p+1,p+n+1,cmpy);
	for(i=1;i<=n;i++)	s[i]=pos[i]=i;
	for(i=1;i<=n;i++)	for(j=i+1;j<=n;j++)	l[++tot].k=atan2(p[j].y-p[i].y,p[j].x-p[i].x),l[tot].a=i,l[tot].b=j;
	sort(l+1,l+tot+1,cmpk);
	ans=999999999;
	for(i=1;i<=tot;i++)
	{
		if(pos[l[i].a]>pos[l[i].b])	swap(l[i].a,l[i].b);
		if(pos[l[i].a]>1)	calc(s[pos[l[i].a]-1],l[i].a,l[i].b);
		if(pos[l[i].b]<n)	calc(s[pos[l[i].b]+1],l[i].a,l[i].b);
		swap(pos[l[i].a],pos[l[i].b]);
		s[pos[l[i].a]]=l[i].a,s[pos[l[i].b]]=l[i].b;
	}
	printf("%.2lf",ans);
	return 0;
}
时间: 2024-08-24 05:57:38

【BZOJ3707】圈地 几何的相关文章

BZOJ3707 圈地

只会O(n ^ 3)路过= = OrzOrzOrzOrzOrz "出题人题解: 显然,这时候暴力枚举会T.于是我们转变一下思路,如果我们确定了2个点以后,第三个点有必要去盲目的枚举吗?答案是否定的.实际上我们把经过这两点的线看成一个斜率,把他当成y轴你会发现第三个点明显是在坐标系左右找一个离”y轴”最近的点来算面积更新答案.然后我们可以继续思考,发现我们可以把点按照某个斜率当成”y轴”进行“从左到右”的排序,这样当2点共线的时候,用这两个点的左右2个点去更新答案就好了.也就是说我们采用旋转坐标系

【BZOJ3707】圈地 计算几何 旋转坐标系

链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/46608743"); } 题解: 对于一个点对,如果它的连线的方程的 x 为定值 ,即为一条竖线,那么我可以把所有点以 x 为第一键值, y 为第二键值排序,然后这条线两端的第一个点与这条线段做个三角形,其面积都可能更

相遇3000亿美金之巅,阿里腾讯战力与血值几何?

五年前,阿里一年的收入比不上腾讯一个季度的收入.2011年,阿里巴巴全年总收入64亿,淘宝刚扭亏为盈.而2011年的腾讯,Q4营收就达到79亿,全年营收284亿,当年利润超百亿.曾经完全不在一个量级的两家公司,如今成了中国互联网的唯二两巨头 -- 市值双超3000亿美金(≈2万亿人民币).阿里昨晚(5月18日)发了华丽丽的2017财年财报,腾讯前两天也刚刚发布了同样亮眼的一季报.去年8月,阿里.腾讯市值双双超过"宇宙第一大行"工商银行,9月,再超中国移动,成为亚洲最大市值两巨头.这是个

一篇令所有游戏圈的兄弟汗颜的文章

回想起上个世纪末,华人游戏圈还处于原始阶段,那时候随便竖几条枪占个山头就敢说自己是做游戏的,拿出来的东西勉强有个模样就不错了,Bug少点那得是国货精品.真正的国货精品又怎么样?一些玩家说:"玩过FF6我才知道我们的精品(<仙剑奇侠传>)跟人家的差得那么远."那还是跟FF6比,现在的仙剑奇侠传3跟FF7又是什么差距呢?天晓得.但在中国,人们就认为<仙剑奇侠传>是最好的RPG.总结这种现象的时候,很多人不约而同地把"中国语言和地道的民族题材"当作

校招真题练习029 圈地运动(360)

圈地运动 圈地运动,就是用很多木棍摆在地上组成一个面积大于0的多边形- 小明喜欢圈地运动,于是他需要去小红店里面买一些木棍,期望圈出一块地来.小红想挑战一下小明,所以给小明设置了一些障碍.障碍分别是:1.如果小明要买第i块木棍的话,他就必须把前i-1块木棍都买下来.2.买了的木棍都必须用在圈地运动中.那么请问小明最少买多少根木棍,才能使得木棍围成的图形是个面积大于0多边形呢? 输入描述:第一行一个数n,表示木棍个数.第二行n个数,第i个数表示第i个木棍的长度ai1<=n<=100001<

URAL - 1963(几何)

不知道是不是几何题,反正就是找对称,值得注意的是,对称轴不一定过点,还可能在边上 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const double mm=1e-7; double x[10],y[10]; bool deng(double a,double

《善圈第26期天天圈》:善圈520,鞠躬迎老兵!

亮点:<善圈第26期天天圈>5.20今日精彩回顾:善圈520,鞠躬迎老兵! 深圳罗湖京基100大厦71层善圈,今天迎来了一位尊贵的客人,他是共和国功臣,一位抗美援朝的英雄老兵--现年83岁的老爷爷陈碧.只见他身穿昔日的绿色军装,挂满了各种军功章. 老人家精神矍铄地向大家行军礼,参加学习的企业家纷纷与老人家合影留念,聆听英雄老兵讲述峥嵘岁月的战斗故事. 著名作家魏巍<谁是最可爱的人>将人们的记忆,回放到60多年前那场让全世界为之瞩目的抗美援朝战争.曾经多少优秀中华儿女,雄赳赳气昂昂跨

iOS Core Image-----十行代码实现微信朋友圈模糊效果

昨天下午微信的朋友圈着实火了一把,在这之后好多程序员都通过抓包工具看到了原图,但是我却在想,网上说是在移动前端做到的那是怎么做到的呢,经过一些学习,终于掌握了一些Core Image的知识,做出了相应的效果,仅仅十行代码 UIImageView * imgView = [[UIImageView alloc]init]; imgView.frame = CGRectMake(50, 50, 200, 200); [self.view addSubview:imgView]; UIImage *

基于微信群控系统分析几十万几百万用户微信朋友圈和聊天记录数据

基于微信群控系统分析几十万几百万用户朋友圈和聊天记录数据打造针对用户的智能推荐系统 用户属性: 姓名.性别.年龄.所在地区.常驻地区.手机号码.微信号码.职业.岗位.身份证等等 用户行为:1.通过图文分析,定位所在区域.行业.大概的收入状况.喜好:2.如果是微商,分析常发微信圈产品:3.综合分析朋友圈人气状况:4.给用户打标签:5.产品匹配. 建立用户画像标签和大数据分析实现智能推荐系统 需要用到的技术 朋友圈抓取技术.高并发架构.大数据分析架构 安卓开发 python  mongodb spa