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



Sample input:
7
2 1
0 0
1 2
2 2
4 2
1 3
3 3


Sample output:
5
0 0
2 1
4 2
3 3
1 3

Submission status: Runtime Error

Solution code:
from collections import deque

def isCLKWISE(ph):
    return not ((ph[-1][0] - ph[-3][0])*(- ph[-3][1] + ph[-2][1]) - (ph[-2][0] - ph[-3][0])*(- ph[-3][1] + ph[-1][1] ) < 0)
      
def ConvexHullScan(P):
    P = sorted(P)
    phU = [P[0],P[1]]
    for p in P[2:]:
        phU.append(p)
        while(True):
            if isCLKWISE(phU) : break
            else :
                del phU[-2]
                if len(phU) == 2 : break
    phL = [P[-1],P[-2]]
    for p in P[-3::-1]:
        phL.append(p)
        while(True):
            if isCLKWISE(phL) : break
            else :
                del phL[-2]
                if len(phL) == 2 : break
    ph = phU + phL[1:-1]
    return ph
  
n = range(int(input()))
P = []
for i in n : P.append([int(x) for x in input().split()])
Q = deque(ConvexHullScan(P))
Q.reverse()
print(len(Q))
idx = min([[x[1][1],x[1][0],x[0]] for x in enumerate(Q)])[2]
Q.rotate(idx)
for r in Q : print(q[0],q[1])

Submission status: Runtime Error

Solution code:
def isCLKWISE(ph) : return not ((ph[-1][0] - ph[-3][0])*(- ph[-3][1] + ph[-2][1]) - (ph[-2][0] - ph[-3][0])*(- ph[-3][1] + ph[-1][1] ) < 0)
      
def ConvexHullScan(P) :
 P = sorted(P)
 phU = []
 phU.append(P[0])
 phU.append(P[1])
 for p in P[2:] :
  phU.append(p)
  if isCLKWISE(phU) : continue
  while(True):
   del phU[-2]
   try:
    if isCLKWISE(phU) : break
   except IndexError : break
 phL = []
 phL.append(P[-1])
 phL.append(P[-2])
 for p in P[-3::-1] :
  phL.append(p)
  if isCLKWISE(phL) : continue
  while(True) :
   del phL[-2]
   try:
    if isCLKWISE(phL) : break
   except IndexError : break
 del phL[0]
 del phL[-1]
 ph = phU + phL
 return ph
  
n = range(int(input()))
P = [[int(x) for x in input().split()] for _ in n]
P = ConvexHullScan(P)
print(len(P.reverse()))
idx = min([[x[1][1],x[1][0],x[0]] for x in enumerate(P)])[2]
for p in P[idx:] + P[:idx] : print(p[0],p[1])

Submission status: Runtime Error

Solution code:
def isCLKWISE(ph) : return not ((ph[-1][0] - ph[-3][0])*(- ph[-3][1] + ph[-2][1]) - (ph[-2][0] - ph[-3][0])*(- ph[-3][1] + ph[-1][1] ) < 0)
      
def ConvexHullScan(P) :
 P = sorted(P)
 phU = []
 phU.append(P[0])
 phU.append(P[1])
 for p in P[2:] :
  phU.append(p)
  if isCLKWISE(phU) : continue
  while(True)???:
   del phU[-2]
   try???:
    if isCLKWISE(phU) : break
   except IndexError : break
 phL = []
 phL.append(P[-1])
 phL.append(P[-2])
 for p in P[-3::-1] :
  phL.append(p)
  if isCLKWISE(phL) : continue
  while(True) :
   del phL[-2]
   try:
    if isCLKWISE(phL) : break
   except IndexError : break
 del phL[0]
 del phL[-1]
 ph = phU + phL
 return ph
  
n = range(int(input()))
P = [[int(x) for x in input().split()] for _ in n]
P = ConvexHullScan(P)
P.reverse()
print(len(P))
idx = min([[x[1][1],x[1][0],x[0]] for x in enumerate(P)])[2]
for p in P[idx:] + P[:idx] : print(p[0],p[1])

Submission status: Runtime Error

Solution code:
#sort ??§??????????????????????????????
def isCLKWISE(ph) : return not ((ph[-1][0] - ph[-3][0])*(- ph[-3][1] + ph[-2][1]) - (ph[-2][0] - ph[-3][0])*(- ph[-3][1] + ph[-1][1] ) < 0)
      
def ConvexHullScan(P) :
 P = sorted(P)
 phU = []
 phU.append(P[0])
 phU.append(P[1])
 for p in P[2:] :
  phU.append(p)
  if isCLKWISE(phU) : continue
  while(True) :
   del phU[-2]
   try???:
    if isCLKWISE(phU) : break
   except IndexError : break
 phL = []
 phL.append(P[-1])
 phL.append(P[-2])
 for p in P[-3::-1] :
  phL.append(p)
  if isCLKWISE(phL) : continue
  while(True) :
   del phL[-2]
   try:
    if isCLKWISE(phL) : break
   except IndexError : break
 del phL[0]
 del phL[-1]
 ph = phU + phL
 return ph
  
n = range(int(input()))
P = [[int(x) for x in input().split()] for _ in n]
P = ConvexHullScan(P)
P.reverse()
print(len(P))
idx = min([[x[1][1],x[1][0],x[0]] for x in enumerate(P)])[2]
for p in P[idx:] + P[:idx] : print(p[0],p[1])

Submission status: Runtime Error

Solution code:
# O(NlgN) time

# build lower hull and upper hull in clockwise, concatenate them get convex hull

def convexHull(points):
  assert len(points) > 0

  points = sorted(set(points))

  # build lower hull
  lower = []
  for p in points:
    # cross(o, a, b) <= 0 not clockwise
    while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
      lower.pop()
    lower.append(p)
  
  # build upper hull
  upper = []
  for p in points[::-1]:
    while len(upper) >= 2 and cross(upper[-2], upper[-1], p) <= 0:
      upper.pop()
    upper.append(p)

  # concatenation of the lower and upper hulls gives the convex hull
  return lower[:-1] + upper[:-1]



# cross product of OA and OB vectors
# U(ou) = u1x + u2y,        V(ov) = v1x + v2y
# UxV = det |u1 u2| = (u1*v2) - (v1*u2) = (u[0]-o[0])*(v[1]-o[1]) - (u[1]-o[1])*(v[0]-o[0])
#           |v1 v2|
def cross(O, A, B):
  return (A[0] - O[0]) * (B[1] - O[1]) - (A[1] - O[1]) * (B[0] - O[0])

# assert convexHull([(i//10, i%10) for i in range(100)]) == [(0, 0), (9, 0), (9, 9), (0, 9)]



if __name__ == '__main__':
    _input = sys.stdin.readlines()
    points = int(_input[0])
    p_info = map(lambda x: x.split(), _input[1:])
    polygon = [(int(x), int(y)) for x, y in p_info]
    ans = convexHull(polygon)
    print(len(ans))
    for x, y in ans:
      print(x, y)