program ghostbusters(input, output); const MAX_GHOSTS = 50; type spot = record x : integer; y : integer; end; spot_arr = array[1..MAX_GHOSTS] of spot; var ghosts : spot_arr; busters : spot_arr; num,i : integer; function line_okay(vertical:integer; slope:real; intercept:real; ghost:integer; buster:integer; start:integer; finish:integer):integer; forward; function read_arrs : integer; var num,i : integer; begin readln(num); for i:= 1 to num do begin readln(ghosts[i].x, ghosts[i].y); end; for i:= 1 to num do begin readln(busters[i].x, busters[i].y); end; read_arrs := num; end; function from_line(vertical:integer; slope:real; intercept:real; pt: spot) : real; var res: real; begin if (vertical <> 0) then begin res := pt.x - intercept; end else begin res := pt.y - ((slope * pt.x) + intercept); end; from_line := res; end; procedure swap_points(var x, y: spot); var temp: spot; begin temp := x; x := y; y := temp; end; function partition(vertical : integer; slope, intercept: real; var arr : spot_arr; start, finish: integer) : integer; label 2; var orig_start : integer; begin orig_start := start; while (start <= finish) do begin while ((start <= finish) and (from_line(vertical, slope, intercept, arr[start]) < 0.0)) do begin start := start + 1; end; if (start > finish) then goto 2; while ((start <= finish) and (from_line(vertical, slope, intercept, arr[finish]) > 0.0)) do begin finish := finish - 1; end; if (finish < start) then goto 2; swap_points(arr[start], arr[finish]); end; 2: partition := start - orig_start; end; procedure solve (start, finish:integer); label 1; var ghost, buster : integer; slope, intercept : real; vertical : integer; num_below : integer; begin if (start < finish) then begin {find pivot (correct line), move it to front, re-partition, recurse} for ghost:= start to finish do begin for buster:= start to finish do begin if (ghosts[ghost].x = busters[buster].x) then begin vertical := 1; intercept := busters[buster].x; end else begin vertical := 0; slope := ((ghosts[ghost].y-busters[buster].y)/(ghosts[ghost].x -busters[buster].x)); intercept := (ghosts[ghost].y - ghosts[ghost].x * slope); end; if (line_okay(vertical, slope, intercept, ghost, buster,start,finish) <> 0) then begin swap_points(ghosts[ghost], ghosts[start]); swap_points(busters[buster], busters[start]); num_below := partition(vertical, slope, intercept, ghosts, start + 1, finish); num_below := partition(vertical, slope, intercept, busters, start + 1, finish); solve(start + 1, start + num_below); solve(start + num_below + 1, finish); goto 1; end; end; end; writeln('Cant find a line!'); end; 1:end; function line_okay; var gcnt, bcnt, i : integer; begin gcnt := 0; bcnt := 0; for i:= start to finish do begin if ((i <> ghost) and (from_line(vertical, slope, intercept, ghosts[i]) > 0)) then begin gcnt:= gcnt+1; end; if ((i <> buster) and (from_line(vertical, slope, intercept, busters[i]) > 0)) then begin bcnt:=bcnt+1; end; end; if (gcnt = bcnt) then begin line_okay := 1; end else begin line_okay := 0; end; end; begin num := read_arrs; solve(1, num); writeln(num); for i:= 1 to num do begin writeln(ghosts[i].x, ' ', ghosts[i].y, ' ', busters[i].x, ' ', busters[i].y); end; end.