POJ 2187 Beauty Contest 旋转卡壳入门题

入门:http://blog.csdn.net/accry/article/details/6070626

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 50005

struct point
{
    int x, y;
}p[maxn], res[maxn<<1];

int max(int a, int b)
{
    return a > b ? a : b;
}

int xmult(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)
{
    return a.y < b.y || a.y == b.y && a.x < b.x;
}

int dis(point a, point b)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

int graham(int n, point *p)
{
    int top = 1, i;    
    sort(p, p + n, cmp);
    if(n == 0) return 0;
    res[0] = p[0];
    if(n == 1) return 1;
    res[1] = p[1];
    if(n == 2) return 2;
    for(i = 3; i < n; i++)
    {
        while(top >= 1 && xmult(res[top-1], res[top], p[i]) <= 0) 
            top--;
        res[++top] = p[i];
    }
    res[++top] = p[n-2];
    int t = top;
    for(i = n-3; i >= 0; i--)
    {
        while(top >= t && xmult(res[top-1], res[top], p[i]) <= 0)
            top--;
        res[++top] = p[i];
    }
    return top;
}

int rotating_calipers(int n, point *p)
{
    int i, q = 1, ans = 0;
    p[n] = p[0];
    for(i = 0; i < n; i++)
    {
        while( xmult(p[i], p[i+1], p[q+1]) > xmult(p[i], p[i+1], p[q]))
            q = (q + 1) % n;
        ans = max(ans, max(dis(p[i], p[q]), dis(p[i+1], p[q+1]) ) );
    }
    return ans;
}
int main()
{
    int i, j;
    int n;
    while( ~scanf("%d", &n))
    {
        for(i = 0; i < n; i++)
            scanf("%d%d", &p[i].x, &p[i].y);
        int cnt = graham(n, p);
        printf("%d\n", rotating_calipers(cnt, res) );
    }
    return 0;
}
posted @ 2012-10-09 23:11  To be an ACMan  Views(219)  Comments(0)    收藏  举报