您的位置:首页 > 其它

北大ACM2187——Beauty Contest

2015-09-12 21:56 225 查看
题目的意思是给你N个点,求各对点之间的距离的最大值的平方。

由于N很大,暴力的方法不行,所以就要去点一些没有必要计算的点,也就是求凸包。

凸包的求解方法,就是将所有点排序之后,第一个和最后一个必定是凸包上的点,剩下的就是从上和从下两个方向继续求解凸包上的点。

不懂的可以看这个:http://www.cnblogs.com/jbelial/archive/2011/08/05/2128625.html

这里不在多说。

将凸包上的点进行暴力的方法求解,就可以求出来。

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

const double EPS = 1e-10;

double add(double a, double b)
{
if(abs(a + b) < EPS * (abs(a) + abs(b)))
return 0;
return a + b;
}

struct P     //点的结构体,重载了 + - * 号,以及实现了内积和外积
{
double x, y;
P(){}
P(double x, double y) : x(x), y(y){}
P operator + (P p)
{
return P(add(x, p.x), add(y, p.y));
}
P operator - (P p)
{
return P(add(x, -p.x), add(y, -p.y));
}
P operator * (double d)
{
return P(x * d, y * d);
}
double dot(P p)
{
return add(x * p.x, y * p.y);
}
double det(P p)
{
return add(x * p.y, -y * p.x);
}
};

int N;
P ps[50001];

bool cmp_x(const P& p, const P& q)   //点如何排序的
{
if(p.x != q.x)
return p.x < q.x;
return p.y < q.y;
}
vector<P> get(P* ps, int n)        //获取凸包
{
sort(ps, ps + n, cmp_x);
int k = 0, i, t;
vector<P> qs(n * 2);
for(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(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(P p, P q)
{
return (p - q).dot(p - q);
}
double max(double a, double b)
{
return a > b ? a : b;
}

void solve()
{
vector<P> qs = get(ps, N);
double res = 0;
for(int i = 0; i < qs.size(); i++)  //枚举凸包的点
{
for(int j = 0; j < i; j++)
{
res = max(res, dist(qs[i], qs[j]));
}
}
printf("%.0lf\n", res);
}

int main()
{
while(scanf("%d", &N) != EOF)  //输入
{
for(int i = 0; i < N; i++)
scanf("%lf%lf", &ps[i].x, &ps[i].y);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: