poj 2187 最远点对

题意:

给出n个点,求最远点对的距离。

限制:

2 <= n <= 5*1e4

思路:

凸包,旋转卡壳

/*poj 2187
  题意:
  给出n个点,求最远点对的距离。
  限制:
  2 <= n <= 5*1e4
  思路:
  凸包,旋转卡壳
 */
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
const double EPS=1e-10;
struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){ x=_x; y=_y; }
	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y); }
	Point operator * (double d){ return Point(d*x,d*y); }
	double dot(Point p){ return x*p.x+y*p.y; }	//内积
	double det(Point p){ return x*p.y-p.x*y; }
};
bool cmpxy(const Point &p,const Point &q){
	if(p.x!=q.x) return p.x<q.x;
	return p.y<q.y;
}
vector<Point> convex_hull(Point *ps,int n){	//凸包要注意退化成2个点,1个点的情况
	sort(ps,ps+n,cmpxy);
	int k=0;
	vector<Point> qs(n*2);	//构造中的凸包
	for(int i=0;i<n;++i){	//构造凸包的下侧
		while(k>1 && (qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) --k;
		qs[k++]=ps[i];
	}
	for(int i=n-2,t=k;i>=0;--i){	//构造凸包的上侧
		while(k>t && (qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) --k;
		qs[k++]=ps[i];
	}
	qs.resize(k-1);
	return qs;
}
double dist(Point p,Point q){
	return (p-q).dot(p-q);
}
const int N=1e5+5;
Point ps[N];
void xzqk(int n){
	vector<Point> qs=convex_hull(ps,n);
	n=qs.size();
	if(n==2){	//特别处理凸包退化的情况
		printf("%.0f\n",dist(qs[0],qs[1]));
		return ;
	}
	int i=0,j=0;
	for(int k=0;k<n;++k){
		if(!cmpxy(qs[i],qs[k])) i=k;
		if(cmpxy(qs[j],qs[k])) j=k;
	}
	double ans=0;
	int si=i,sj=j;
	while(i!=sj || j!=si){
		ans=max(ans,dist(qs[i],qs[j]));
		if((qs[(i+1)%n]-qs[i]).det(qs[(j+1)%n]-qs[j])<0)
			i=(i+1)%n;
		else
			j=(j+1)%n;
	}
	printf("%.3f\n",sqrt(ans));
}
int main(){
	int T;
	int n;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=0;i<n;++i)
			scanf("%lf%lf",&ps[i].x,&ps[i].y);
		xzqk(n);
	}
	return 0;
}

时间: 2024-10-05 21:51:35

poj 2187 最远点对的相关文章

【POJ 2187】 Beauty Contest (凸包-Graham扫描算法)

[POJ 2187] Beauty Contest (凸包-Graham扫描算法) 找平面最远点对 数据很大 用暴力会T..我感觉-- 扫描出个凸包 然后枚举凸包上的点即可 没坑 int也可过 注意重边跟共线就行 代码下附赠几组数据 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include

POJ 2187 旋转卡壳 + 水平序 Graham 扫描算法

水平序 Graham 扫描算法: 计算二维凸包的时候可以用到,Graham 扫描算法有水平序和极角序两种. 极角序算法能一次确定整个凸包, 但是计算极角需要用到三角函数,速度较慢,精度较差,特殊情况较多. 水平序算法需要扫描两次,但排序简单,讨论简单,不易出错. [算法流程] 1.对顶点按x为第一关键字,y为第二关键字进行排序. 2.准备一个空栈,并将前两个点压入栈. 3.对于每一个顶点A,只要栈顶中还至少两个顶点,记栈顶为T,栈中第二个为U. 若UT(向量) * TA(向量) <= 0, 则将

poj 2187 Beauty Contest——旋转卡壳

题目:http://poj.org/problem?id=2187 学习材料:https://blog.csdn.net/wang_heng199/article/details/74477738 https://www.jianshu.com/p/74c25c0772d6 可以再倒着枚举一遍那样求凸包. 用叉积算面积来旋转卡壳. 注意在面积等于的时候就不要往后走了,不然只有两个点的数据就会死循环. #include<cstdio> #include<cstring> #inclu

POJ 2187 求凸包上最长距离

简单的旋转卡壳题目 以每一条边作为基础,找到那个最远的对踵点,计算所有对踵点的点对距离 这里求的是距离的平方,所有过程都是int即可 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 #

poj 2187【旋转卡壳】

求平面最远点对 #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int N=50005; int n,w=1,top; double ans; struct dian { double x,y; dian(double X=0,double Y=0) { x=X,y=Y; } dian operator + (

POJ 2187 Beauty Contest

题意: 题目链接 给定 \(n\) 个点,求距离最远的两个点之间的距离,输出最远距离的平方 \(n<=50000\) 思路: 旋转卡壳... 注意事项: 数组名称不要弄混了 code: #include<cstdio> #include<algorithm> using namespace std; const int N=50005; int n,top,per[N],res; struct point{int x,y;int dist(){return x*x+y*y;}

poj 2187 N个点中输出2点的最大距离的平方

旋转卡壳 Sample Input 40 00 11 11 0Sample Output 2 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <string> 6 # include <cmath> 7 # include <queue> 8 # define LL l

poj 2187

求凸包后枚举凸包上的点 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

[转] POJ几何分类

转自:http://blog.csdn.net/tyger/article/details/4480029 计算几何题的特点与做题要领:1.大部分不会很难,少部分题目思路很巧妙2.做计算几何题目,模板很重要,模板必须高度可靠.3.要注意代码的组织,因为计算几何的题目很容易上两百行代码,里面大部分是模板.如果代码一片混乱,那么会严重影响做题正确率.4.注意精度控制.5.能用整数的地方尽量用整数,要想到扩大数据的方法(扩大一倍,或扩大sqrt2).因为整数不用考虑浮点误差,而且运算比浮点快. 一.点