Problem:
Convex Hull

Find the convex hull of a given set of points P. In other words, find the smallest convex polygon containing all the points of P. Here, in a convex polygon, all interior angles are less than or equal to 180 degrees.

Please note that you should find all the points of P on both corner and boundary of the convex polygon.

Input

n
x1 y1
x2 y2
:
xn yn

The first integer n is the number of points in P. The coordinate of the i-th point pi is given by two integers xi and yi.

Output

In the first line, print the number of points on the corner/boundary of the convex polygon. In the following lines, print x y coordinates of the set of points.
The coordinates should be given in the order of counter-clockwise visit of them starting from the point in P with the minimum y-coordinate, or the leftmost such point in case of a tie.

Constraints

3 ≤ n ≤ 100000

-10000 ≤ xi, yi ≤ 10000

No point in the P will occur more than once.

Sample Input 1

7
2 1
0 0
1 2
2 2
4 2
1 3
3 3

Sample Output 1

5
0 0
2 1
4 2
3 3
1 3

Sample Input 2

4
0 0
2 2
0 2
0 1

Sample Output 2

4
0 0
2 2
0 2
0 1

Solution in C (judge verdict: Accepted)

#include <sys/types.h>
#include <stdlib.h>
#define MAX_INPUT 100000
/*??????????±???????????????°??????*/
typedef struct point_t{
  int x;
  int y;
}point_t ;

typedef point_t* point_ptr_t;

int compare(const void*, const void*);
static double ccw(point_t*, point_t*, point_t*);
void convex_hull(point_t*, size_t, point_ptr_t**, size_t*);

int main(void)
{
    size_t npoints = 0; 
    int i;
    struct point_t aPoints[MAX_INPUT];
    point_ptr_t *ppHull;
    size_t hullsize = 0;

/*??§?¨??????????????????????*/
    for(i = 0; i < MAX_INPUT; i++){
        aPoints[i].x = NULL;
        aPoints[i].y = NULL;
    }



    scanf("%d", &npoints);
    for (i = 0; i < npoints; i++){
        scanf("%d %d", &aPoints[i].x, &aPoints[i].y);
    }

/*y??§?¨???§??????????????????*/
    qsort(aPoints, npoints, sizeof(point_t), compare);
/*y??§?¨?????????????????£????x??§?¨???§??????????????????*/
        if(aPoints[0].y == aPoints[1].y && aPoints[0].x > aPoints[1].x)
        {
            point_t temp;
            temp = aPoints[0];
            aPoints[0] = aPoints[1];
            aPoints[1] = temp;
        }
        if(aPoints[1].y == aPoints[2].y && aPoints[1].x > aPoints[2].x)
        {
            point_t temp;
            temp = aPoints[1];
            aPoints[1] = aPoints[2];
            aPoints[2] = temp;
        }
        if(aPoints[0].y == aPoints[2].y && aPoints[0].x > aPoints[2].x)
        {
            point_t temp;
            temp = aPoints[0];
            aPoints[0] = aPoints[2];
            aPoints[2] = temp;
        }
    for(i = 2; i < npoints - 1; i++)
    {
        if(aPoints[i].y == aPoints[i+1].y && aPoints[i].x > aPoints[i+1].x)
        {
            point_t temp;
            temp = aPoints[i];
            aPoints[i] = aPoints[i+1];
            aPoints[i+1] = temp;
            i -= 2;
        }
    }    

/*??????????????§??????
 *  for(i = 0; i < npoints; i++){
 *      printf("%d %d\n", aPoints[i].x, aPoints[i].y);
 *  }
 */
/*??????????±???????*/
    ppHull = (point_ptr_t*)calloc(npoints, sizeof(point_ptr_t*));
    if (ppHull == NULL)
    {
        printf("memory error");
    }

    for(i = 0; i < npoints; i++)
    {
        ppHull[i] = NULL;
    }
    convex_hull(aPoints, npoints, &ppHull, &hullsize);

    printf("%d\n", hullsize);
    for(i = 0; i < hullsize; i++){
         printf("%d %d\n", ppHull[i]->x, ppHull[i]->y);
    }

/*    free(*outhull);
    free(outhull);
*/
    return 0;
}

/* ????????¢??° */
int compare(const void* c1, const void* c2)
{
    point_t t1 = *(point_t *)c1;
    point_t t2 = *(point_t *)c2;

    if(t1.y < t2.y){            /*y??§?¨???§?????????*/
        return -1;
    }else if(t1.y > t2.y){
        return 1;
    }else return 0;
}
/*??????????????????????????????????????????????????????
 *ccw > 0 ??§???????¨?????????????ccw < 0??§????¨???????
 */
inline static double ccw(point_t* p1, point_t* p2, point_t* p3)
{
    return (p2->x - p1->x)*(p3->y - p1->y) - (p2->y - p1->y)*(p3->x - p1->x);
}

/* ???????¨???????????????§???????????????????????????????????????
 * ?????????????´???¨?????????????´??????????????????¨???
 */
void convex_hull(point_t* points, size_t npoints, point_ptr_t** out_hull, size_t* out_hullsize)
{
    point_ptr_t* hull;
    int i, t;
    int k = 0;

    hull = *out_hull;

/* right hull */
    for (i = 0; i < npoints; ++i) {
        while (k >= 2 && ccw(hull[k-2], hull[k-1], &points[i]) < 0) --k;
        hull[k++] = &points[i];
    }

/* left hull */
    for (i = npoints - 2, t = k + 1; i >= 0; --i) {
        while (k >= t && ccw(hull[k-2], hull[k-1], &points[i]) < 0) --k;
        hull[k++] = &points[i];
    }
  
    *out_hull = hull;
    *out_hullsize = k - 1;

}