Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Graham求凸包以后O(N)找最远点对,RE了无数次……只有两个点和一条线的情况都考虑了,请各位gg帮忙看看哪里不对。。。

Posted by FailedWing at 2007-06-18 10:53:48 on Problem 2187
#include<iostream>
#include<cmath>

using namespace std;

int             n, mx, my;
int             stack[50000 + 100];
struct          node
{
    int         x, y;
}               que[50000 + 100];

bool            cmp(node a, node b)
{
    int         t, d1, d2;
    if ((mx == a.x) && (my == a.y))
        return true;
    if ((mx == b.x) && (my == b.y))
        return false;
    t = (a.x - mx) * (b.y - my) - (b.x - mx) * (a.y - my);
    if (t > 0)
        return true;
    else
        if (t < 0)
            return false;
        else
        {
            d1 = (a.x - mx) * (a.x - mx) + (a.y - my) * (a.y - my);
            d2 = (b.x - mx) * (b.x - mx) + (b.y - my) * (b.y - my);
            if (d1 > d2)
                return true;
            else
                return false;
        }
}

int           cross(int a, int b, int c)
{
    return (que[a].x - que[c].x) * (que[b].y - que[c].y) - (que[b].x - que[c].x) * (que[a].y - que[c].y);
}

int           dist(int a, int b)
{
    return (que[a].x - que[b].x) * (que[a].x - que[b].x) + (que[a].y - que[b].y) * (que[a].y - que[b].y);
}

int             main()
{
    int         i, k, t, j, ans;
    while (scanf("%d", &n) != -1)
    {
        mx = 10001;
        my = 10001;
        for (i = 0; i < n; i ++)
        {
            scanf("%d%d", &que[i].x, &que[i].y);
            if ((que[i].y < my) || ((que[i].y == my) && (que[i].x < mx)))
            {
                mx = que[i].x;
                my = que[i].y;
                k = i;
            }
        }
        swap(que[0], que[k]);
        sort(que, que + n, cmp);
        ans = dist(0, 1);
        stack[0] = 0;
        stack[1] = 1;
        t = 1;
        for (i = 2; i < n; i ++)
            if (cross(0, 1, i) != 0)
            {
                stack[2] = i;
                t ++;
                break;
            }
        if (t == 1)
        {
            printf("%d\n", ans);
            continue;
        }
        for (i = stack[t] + 1; i < n; i ++)
        {
            if (cross(i, i - 1, 0) == 0)
                continue;
            while ((t >= 1) && (cross(i, stack[t], stack[t - 1]) >= 0))
                t --;
            t ++;
            stack[t] = i;
        }
        j = 1;
        t ++;
        stack[t] = 0;
        for (i = 0; i < t; i ++)
        {
            while ((j <= t) && (dist(stack[i], stack[j]) > dist(stack[i], stack[j - 1])))
                j ++;            
            if (dist(stack[i], stack[j - 1]) > ans)
                ans = dist(stack[i], stack[j - 1]);
        }
        printf("%d\n", ans);
    }
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator