poj 2187

来源:互联网 发布:pmp考试 知乎 编辑:程序博客网 时间:2024/05/29 07:45

求最远点对的距离。

典型的旋转卡壳。卡了好久一直WA,直接凸包,暴力枚举,300ms。水题啊。旋转卡壳果然不是一般的卡。

原来旋转卡壳写错了。!!!!!!!!

果然第一次啊!!!!!处女作!


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;


struct point {
double x,y;
};
point data[50010]={};
point stack[50010]={};
int n,top;
long long dis(point a,point b) {
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int cross(point o,point a,point b) {
return (a.x - o.x)*(b.y-o.y) - (a.y-o.y)*(b.x-o.x);
}
bool cmp(point a,point b) {
if(cross(data[0],a,b) > 0 || (cross(data[0],a,b) == 0 && dis(data[0],a) < dis(data[0],b)))
 return 1;
return 0;
}
bool cmp1(point a,point b) {
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
/*bool line() {
bool flag1 = 0,flag2 = 0,flag3 = 0;
for(int i = 1; i < top; i++)
 if(stack[i].x != stack[i-1].x) {
 flag1 = 1;
 break;
 }
for(int i = 1; i < top; i++)
 if(stack[i].y != stack[i-1].y) {
 flag2 = 1;
 break;
 }
for(int i = 1; i < top; i++)
 if(fabs(stack[i].y/stack[i].x - stack[i-1].y/stack[i-1].x) < 0.00005) {
 flag3 = 1;
 break;
 }
if(flag1 || flag2 || flag3)
 return 1;
return 0;
}*/
void graham() {
top = 0;
sort(data+1,data+n,cmp);


for(int i = 0; i < n; i++) {
while(top >= 2 && cross(stack[top-2],stack[top-1],data[i]) <= 0)     // cross == 0删除同一条边的中间点
 top--;
stack[top++] = data[i];
}
}
long long dis_ma() {
graham();
int q = 1;
long long ma = dis(stack[0],stack[top-1]);
/*for(int i = 0; i < top; i++)            //暴力枚举凸包上的所有点,
 for(int j = i + 1; j < top; j++)
ma = max(ma,dis(stack[i],stack[j]));*/
for(int i = 1; i < top; i++) {                         //旋转卡壳
while(cross(stack[i-1],stack[i],stack[(q+1)%top]) > cross(stack[i-1],stack[i],stack[q]))
 q = (q+1) % top;
ma = max(ma,max(dis(stack[i-1],stack[q]),dis(stack[i],stack[q])));
}
return ma;
}
int main() {
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%lf %lf",&data[i].x,&data[i].y);
if(data[i].y < data[0].y ||(data[i].y == data[0].y && data[i].x < data[0].x))
 swap(data[i],data[0]);
}
long long sum = dis_ma();
printf("%lld\n",sum);
return 0;
}

0 0
原创粉丝点击