Problem:
Diameter of a Convex Polygon

Find the diameter of a convex polygon g. In other words, find a pair of points that have maximum distance between them.

Input

n
x1 y1
x2 y2
:
xn yn

The first integer n is the number of points in g.

In the following lines, the coordinate of the i-th point pi is given by two real numbers xi and yi. The coordinates of points are given in the order of counter-clockwise visit of them. Each value is a real number with at most 6 digits after the decimal point.

Output

Print the diameter of g in a line. The output values should be in a decimal fraction with an error less than 0.000001.

Constraints

3 ≤ n ≤ 80000

-100 ≤ xi, yi ≤ 100

No point in the g will occur more than once.

Sample Input 1

3
0.0 0.0
4.0 0.0
2.0 2.0

Sample Output 1

4.00

Sample Input 2

4
0.0 0.0
1.0 0.0
1.0 1.0
0.0 1.0

Sample Output 2

1.414213562373

Solution in C (judge verdict: Time Limit Exceeded)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define det(x1, y1, x2, y2) ((x1) * (y2) - (x2) * (y1))
#define distance(x, y) (sqrt(pow(x, 2) + pow(y, 2)))
#define max(x, y) ((x) > (y) ? (x) : (y))

typedef struct {
        double x;
        double y;
} Point;

int compare(Point, Point);
void qsort1(int, int, Point*);
int convex_hull(Point*, Point*, int);
double caliper(Point*, int);
main()
{
        int i, size, qsize;
        Point *ps, *qs;
        scanf("%d", &size);
        ps = (Point*)malloc(sizeof(Point) * size);
        qs = (Point*)malloc(sizeof(Point) * size * 2);
        for (i = 0; i < size; i++) {
                scanf("%lf %lf", &ps[i].x, &ps[i].y);
        }
        qsize = convex_hull(qs, ps, size);
        printf("%.7f\n", caliper(qs, qsize));
        free(ps);
        free(qs);
}

int compare(Point arg1, Point arg2)
{
        double p1 = arg1.x - arg2.x, p2 = arg1.y - arg2.y;
        if (p1 > 0 || (p1 == 0 && p2 > 0)) {
                return 1;
        } else if (p1 < 0 || (p1 == 0 && p2 < 0)) {
                return -1;
        } else {
                return 0;
        }
}

void qsort1(int left, int right, Point *p)
{
    int pivot = (left + right) / 2, i = left, j = right;
    if(left >= right) return;
    do{
        while(compare(p[pivot], p[i]) == 1) i++;
        while(compare(p[pivot], p[j]) == -1) j--;
        if(i <= j){
            Point temp = p[i];
                        p[i] = p[j];
                        p[j] = temp;
            i++;
            j--;
        }
    }while(i <= j);
    qsort1(left, j, p);
    qsort1(i, right, p);
}

int convex_hull(Point *qs, Point *ps, int size)
{
        int i, t, k = 0;
        qsort1(0, size - 1, ps);
        for (i = 0; i < size; i++) {
                while (k > 1 && det(qs[k-1].x - qs[k-2].x, qs[k-1].y - qs[k-2].y,
                                                        ps[i].x - qs[k-1].x, ps[i].y - qs[k-1].y) <= 0) {
                        k--;
                }
                qs[k++] = ps[i];
        }
        for (i = size - 2, t = k; i >= 0; i--) {
        while (k > t && det(qs[k-1].x - qs[k-2].x, qs[k-1].y - qs[k-2].y,
                            ps[i].x - qs[k-1].x, ps[i].y - qs[k-1].y) <= 0) {
            k--;
        }
        qs[k++] = ps[i];
    }
        qs = (Point*)realloc(qs, sizeof(Point) * (k - 1));
        return (k - 1);
}

double caliper(Point *qs, int qsize)
{
        int i, j, k, si, sj;
        double result = 0;
        if (qsize == 2) {
                return distance(qs[0].x - qs[1].x, qs[0].y - qs[1].y);
        }
        for (i = j = k = 0; k < qsize; k++) {
                if (compare(qs[i], qs[k]) == -1) i = k;
                if (compare(qs[j], qs[k]) == 1) j = k;
        }
        si = i;
        sj = j;
        while (i != sj || j != si) {
                result = max(result, distance(qs[i].x - qs[j].x, qs[i].y - qs[j].y));
                if (det(qs[(i+1)%qsize].x - qs[i].x, qs[(i+1)%qsize].y - qs[i].y,
                                qs[(j+1)%qsize].x - qs[j].x, qs[(j+1)%qsize].y - qs[j].y) < 0){
                        i = (i + 1) % qsize;
                } else {
                        j = (j + 1) % qsize;
                }
        }
                return result;
}