nyoj253LK的旅行(旋转卡壳法)

LK的旅行

时间限制:2000 ms  |  内存限制:65535 KB

难度:5

描述

LK最近要去某几个地方旅行,她从地图上计划了几个点,并且用笔点了出来,准备在五一假期去这几个城市旅行。现在希望你找出她点的所有的点中距离最远的两个点的距离是多少。各个景点可以认为是在一个平面上。

输入
第一行有一个整数0<n<10表示测试数据的组数随后的n组数据中,第一行有一个整数3<m<100000表示有m个旅游景点。随后的m行每行有两个整数,分别表示每一个点的x和y。景点坐标中可能有重复的,0<=x,y<=10000)
输出
每组数据输出距离最远的点对的距离的平方.
样例输入
1
4
0 0
1 1
0 1
1 0
样例输出
2

做这个题之前最好先做下78圈水池这题,这两个题差不多,区别在于一个是求哪些点在凸包内,这个是求凸包的两个最远的点的距离的平方。

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define NN 100005
#define max(a,b) ((a)>(b)?(a):(b))
const int INF=1<<30;
typedef struct Point{
	int x,y;
}P;
P a[NN],q[NN];
int top;
int dis_2(P p1,P p2)
{
	return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
int xx(P p,P p1,P p2)
{
	return (p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x);
}
int comp(const void *x,const void *y)
{
	P i=*(P *)x;
	P j=*(P *)y;
	if(i.x!=j.x)
		return i.x-j.x;
	else
		return i.y-j.y;
}
int main()
{
	int N,i,n;
	scanf("%d",&N);
	while(N--)
	{
		scanf("%d",&n);
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&a[i].x,&a[i].y);
		}
		qsort(a,n,sizeof(a[0]),comp);

		top=0;
		q[0]=a[0];
		for(i=1;i<n;i++)//下凸包
		{
			if(a[i].x==q[top].x && a[i].y==q[top].y) continue;
			while(top>=1 && xx(q[top-1],q[top],a[i])>=0) top--;
			q[++top]=a[i];
		}
		int t=top;
		for(i=n-1;i>=0;i--)//上凸包
		{
			if(a[i].x==q[top].x && a[i].y==q[top].y) continue;
			while(top>t && xx(q[top-1],q[top],a[i])>=0) top--;
			q[++top]=a[i];
		}
		double ans=0.0;
		t=1;
		for(i=0;i<top;i++)
		{
			while(xx(q[i+1],q[t],q[i]) > xx(q[i+1],q[t+1],q[i])) t=(t+1)%top;
			ans=max(ans,max(dis_2(q[i],q[t]),dis_2(q[i+1],q[t+1])));
		}
		printf("%.0lf\n",ans);
	}
	return 0;
}
时间: 2024-10-12 03:19:39

nyoj253LK的旅行(旋转卡壳法)的相关文章

LA 4728 Square ,旋转卡壳法求多边形的直径

给出一些正方形,让你求这些正方形顶点之间的最大距离的平方. //返回点集直径的平方 int diameter2(vector<Point> & points) { vector<Point> p = ConvexHull(points); int n = p.size(); if(n==1) return 0; if(n==2) return Dist2(p[0], p[1]); p.push_back(p[0]); int ans = 0; for(int u = 0,

NYOJ_253:LK的旅行(旋转卡壳入门)

题目链接 求平面最大点对. 找凸包 -> 根据凸包运用旋转卡壳算法求最大点对(套用kuang巨模板) 关于旋转卡壳算法 #include<bits/stdc++.h> using namespace std; struct point { int x,y; point operator -(const point& rhs)const { point ret; ret.x=x-rhs.x; ret.y=y-rhs.y; return ret; } int operator *(c

【最小矩形面积覆盖:凸包+旋转卡壳】UVA 10173 Smallest Bounding Rectangle

[最小矩形面积覆盖:凸包+旋转卡壳]UVA 10173 Smallest Bounding Rectangle 题目链接:UVA 10173 Smallest Bounding Rectangle 题目大意 给你n个点,求能够覆盖所有点集的最小矩形面积. 笔者的第2道凸包题目,凸包 + 旋转卡壳,实现点集的最小矩形面积覆盖问题 ">=0"写成"<=0"坑了我一下午!QAQ 说一下思路 ①Graham's Scan法构建凸包,时间复杂度O(nlogn) ②

旋转卡壳总结

[+] 目录(?)[+] 以下所有文章均转载( http://blog.csdn.net/acmaker/article/details/3176910) 转载请注明出处! 1.旋转卡壳——翻译说明文档 前一段时间看了一位国外大牛的网站,是关于旋转卡壳技术的,内容很不错,就尝试着翻译一下. 关于旋转卡壳技术,最早是在刘汝佳.黄亮的<算法艺术与信息学竞赛>上看到的,是计算几何相关的技术,开始觉得很神奇,因为其对于凸多边形的问题给出了很好的解决方案,于是上网查了一下,就发现了这份资料. 通过个人的

P1452 Beauty Contes(旋转卡壳版)

题目背景 此处省略1W字^ ^ 题目描述 贝茜在牛的选美比赛中赢得了冠军”牛世界小姐”.因此,贝西会参观N(2 < = N < = 50000)个农场来传播善意.世界将被表示成一个二维平面,每个农场位于一对整数坐标(x,y),各有一个值范围在-10000…10000.没有两个农场共享相同的一对坐标. 尽管贝西沿直线前往下一个农场,但牧场之间的距离可能很大,所以她需要一个手提箱保证在每一段旅程中她有足够吃的食物.她想确定她可能需要旅行的最大可能距离,她要知道她必须带的手提箱的大小.帮助贝西计算农

uva 12307 - Smallest Enclosing Rectangle(旋转卡壳)

题目链接:uva 12307 - Smallest Enclosing Rectangle 两组踵对点围成长方形,枚举出所有可行长方形维护最小值. #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <complex> #include <algorithm> using namespace std; typedef pair

bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包

[HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 2081  Solved: 920[Submit][Status][Discuss] Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, 输出所求矩形的面积和四个顶点坐标 Input 第一行为一个整数n(3<=n<=50000) 从第2至第n+1行每行有两个浮点数,表示一个顶点的x和y坐标,不用科学计

[模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

//to update 一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算 自适应Simpson 凸包 Andrew 算法, 即分别求上, 下凸包. 时间复杂度 \(O(n \log n)\). struct tvec{db x,y;}; il int dcmp(db a){return fabs(a)<=eps?0:(a>0?1:-1);} il db p2(db a){return a*a;} il db gougu1(db a,db b){retu

BZOJ 1185 HNOI 2007 最小矩形覆盖 旋转卡壳

题目大意:给出平面上的一些点,问面积最小的矩形满足覆盖所有的点. 思路:覆盖问题和不是凸包上的点没关系,先做凸包.根据贪心的思想,这个覆盖了所有点的矩形肯定至少有一条边与凸包上的边重合,那么我们枚举凸包上的每一条边,对于这个已经确定了一条边的矩形,不难确定其他三个边.注意到已知当前直线的向量,就可以求出两侧和对面的向量,而这三个向量随着枚举的边的移动是单调的,所以就可以用旋转卡壳来卡住剩下的三条边. 但是旋转卡壳时的初值会出问题,如果按照逆时针的顺序求出剩下的三条边的时候,要想通过向量直接卡第三