当前位置:编程学习 > C/C++ >>

POJ 2187(凸包GrahamScan扫描+极角排序+平面最远点对)

平面最远点对
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 22454 Accepted: 6868
Description
求 N (2 <= N <= 50,000) 个点平面最远点对距离的平方. 
 
Input
* 第1行:N 
 
接下来每行为点的坐标 x 和 y ,(x,y)(-10,000<=x,y<=10,000的整数). 
Output
输出一行,为平面最远点对距离平方. 
Sample Input
4
0 0
0 1
1 1
1 0
Sample Output
2
Hint
(0, 0) a到 (1, 1) 距离平方为 2 
Source
USACO 2003 Fall
凸包模版题:
先用GrahamScan扫描求凸包,显然最远点对在凸包上。
 
极角排序:
按照逆时针顺序给平面上的点集到一个点的距离排序,使得排序后所有点正好绕这个点一圈.(按距离远近从小到大排
思路:
GrahamScan扫描:
 
 
 

\

\

\

\

\

\

\

\

\

 
 
 
 
 
大致如此.
 
另补:
该题小Bug-有可能所有点在一条直线上。
这样也能求出:
Ex:
a序列(-1,0) (0,0)    (4,0)   (9,0)
则st序列重复如下操作:
(-1,1),(0,0)入队。
(4,0)入队,不左拐->(0,0)出队
队列元素<2 (4,0)入队
……
 
[cpp]  
#include<cstdio>  
#include<cstdlib>  
#include<cstring>  
#include<cmath>  
#include<iostream>  
#include<algorithm>  
#include<functional>  
using namespace std;  
#define MAXN (50000+10)  
double sqr(double x){return x*x;}  
struct P  
{  
    double x,y;  
    P(){}  
    P(double _x,double _y):x(_x),y(_y){}  
}a[MAXN],st[MAXN];  
int dis2(P A,P B)  
{  
    return sqr(A.x-B.x)+sqr(A.y-B.y);  
}  
double dis(P A,P B)  
{  
    return sqrt(double(dis2(A,B)));  
}  
struct V  
{  
    double x,y;  
    V(){}  
    V(double _x,double _y):x(_x),y(_y){}  
    V(P A,P B):x(B.x-A.x),y(B.y-A.y){}  
};  
double operator*(V a,V b)  
{  
    return a.x*b.y-a.y*b.x;  
}  
int cmp(P A,P B) //1:a>b 0:a<=b  
{  
    double tmp=V(a[1],A)*V(a[1],B);  
    if (tmp>0) return 1;  
    else if (tmp==0) return (-(dis(a[1],A)-dis(a[1],B))>0)?1:0;  
    else ret
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,