洛谷P1452 Beauty Contest(凸包模板&旋转卡壳模板)

题目背景

此处省略1W字^ ^

题目描述

贝茜在牛的选美比赛中赢得了冠军”牛世界小姐”。因此,贝西会参观N(2 < = N < = 50000)个农场来传播善意。世界将被表示成一个二维平面,每个农场位于一对整数坐标(x,y),各有一个值范围在-10000…10000。没有两个农场共享相同的一对坐标。

尽管贝西沿直线前往下一个农场,但牧场之间的距离可能很大,所以她需要一个手提箱保证在每一段旅程中她有足够吃的食物。她想确定她可能需要旅行的最大可能距离,她要知道她必须带的手提箱的大小。帮助贝西计算农场的最大距离。

输入输出格式

输入格式:

第一行:一个整数n

第2~n+1行:xi yi 表示n个农场中第i个的坐标

输出格式:

一行:最远距离的[b]平方[/b]

输入输出样例

输入样例#1:  复制
4
0 0
0 1
1 1
1 0
输出样例#1:  复制
2

说明

NONE






题解:凸包模板+旋转卡壳模板。

旋转卡壳其实是个很傻逼的东西:

计算凸多边形上的最远点对(又叫直径)。这样考虑方法:对于每一个点,都求一求它到每个点的距离(这不就跟暴力没有区别了吗!!)。 
这样做会有很多无用功。如果一根筷子边紧贴多边形的一条边,那么离这条边最远的点不就是与它们构成的最大面积的三角形吗?于是乎,每遍历一条边的时候,就把另外一个点朝相同方向转动直到面积最大(这个面积的变化是单峰的),然后求一求几个点的最短距离。(为什么是几个点?)因为另外一根筷子有可能与多边形的另外一条边重合。如下图: 

这里写图片描述



旋转卡壳模板代码:

d[tot+1]=1;//tot为凸包定点个数
    j=3;
	for(i=1;i<=tot;i++){
		while(cha(a[d[i]],a[d[i+1]],a[d[j]])<cha(a[d[i]],a[d[i+1]],a[d[j+1]])){
			j=(j+1)%tot;
			if(j==0)j=tot;
		}
		ans=max(ans,max(dis(a[d[i]],a[d[j]]),dis(a[d[i+1]],a[d[j]])));
	} 
	printf("%.0lf",ans);


非常傻逼。

下面上代码(要特判只有两个点):


#include<bits/stdc++.h>
using namespace std;
struct aaa{
	double l,r;
}a[100001];
int n,i,flag,tot,j,d[100001],l,r;
double ans;
double cha(aaa a,aaa b,aaa c){  
    return(b.l-a.l)*(c.r-a.r)-(c.l-a.l)*(b.r-a.r);  
}  
double dis(aaa a,aaa b){  
    return (b.l-a.l)*(b.l-a.l)+(b.r-a.r)*(b.r-a.r);  
}  
bool cmp(aaa aa,aaa b){  
    double t=cha(a[1],aa,b);  
    return (t>0||(fabs(t)<1e-8&&dis(a[1],aa)<dis(a[1],b)));  
}
int main(){
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%lf%lf",&a[i].l,&a[i].r);  
	if(n==2){
		printf("%.0lf",dis(a[1],a[2]));
		return 0;
	}
    for(i=1;i<=n;i++){  
        if((!flag)||(a[i].l<l)||(a[i].l==l&&a[i].r<r)){  
        flag=i;l=a[i].l;r=a[i].r;  
    }  
    }    
    a[0]=a[1];  
    a[1]=a[flag];  
    a[flag]=a[0];  
    sort(a+2,a+n+1,cmp);   
    tot=3;  
    d[1]=1;d[2]=2;d[3]=3;  
    for(i=4;i<=n;i++){  
        while(tot>=2&&cha(a[d[tot-1]],a[d[tot]],a[i])<=0)tot--;  
        d[++tot]=i;  
    }  
    d[tot+1]=1;
    j=3;
	for(i=1;i<=tot;i++){
		while(cha(a[d[i]],a[d[i+1]],a[d[j]])<cha(a[d[i]],a[d[i+1]],a[d[j+1]])){
			j=(j+1)%tot;
			if(j==0)j=tot;
		}
		ans=max(ans,max(dis(a[d[i]],a[d[j]]),dis(a[d[i+1]],a[d[j]])));
	} 
	printf("%.0lf",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_41510496/article/details/80645794