Problem:
 Score : 400 points    Problem Statement On a two-dimensional plane, there are N red points and N blue points.
The coordinates of the i -th red point are (a_i, b_i) , and the coordinates of the i -th blue point are (c_i, d_i) .  A red point and a blue point can form a friendly pair when, the x -coordinate of the red point is smaller than that of the blue point, and the y -coordinate of the red point is also smaller than that of the blue point.  At most how many friendly pairs can you form? Note that a point cannot belong to multiple pairs.      Constraints  All input values are integers.  1 \leq N \leq 100  0 \leq a_i, b_i, c_i, d_i < 2N  a_1, a_2, ..., a_N, c_1, c_2, ..., c_N are all different.  b_1, b_2, ..., b_N, d_1, d_2, ..., d_N are all different.         Input Input is given from Standard Input in the following format:  N  a_1  b_1  a_2  b_2  :  a_N  b_N  c_1  d_1  c_2  d_2  :  c_N  d_N       Output Print the maximum number of friendly pairs.        Sample Input 1 3
2 0
3 1
1 3
4 2
0 4
5 5      Sample Output 1 2  For example, you can pair (2, 0) and (4, 2) , then (3, 1) and (5, 5) .       Sample Input 2 3
0 0
1 1
5 2
2 3
3 4
4 5      Sample Output 2 2  For example, you can pair (0, 0) and (2, 3) , then (1, 1) and (3, 4) .       Sample Input 3 2
2 2
3 3
0 0
1 1      Sample Output 3 0  It is possible that no pair can be formed.       Sample Input 4 5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7      Sample Output 4 5       Sample Input 5 5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9      Sample Output 5 4

Solution (Python):





num=201 

def dfs(cur):
	global vis
	global EE
	vis[cur] = 1

	if cur==num:
		return 1

	for i in range(num+1):
		if vis[i]==0 and EE[cur][i]>0 and dfs(i) > 0:
			EE[cur][i] -= 1
			EE[i][cur] += 1
			return 1
	return 0




n=int(input())
s=[]
ss=[]
for i in range(n):
    s.append([int(i) for i in input().split()])
for i in range(n):
    ss.append([int(i) for i in input().split()])
s.sort(key=lambda x:(x[0],x[1]))
ss.sort(key=lambda x:(x[0],x[1]))

pair=[]
for i in range(len(s)):
    right=[]
    for j in range(n):    
        if s[j][0]<ss[i][0] and s[j][1]<ss[i][1]:
            right.append(j)
    pair.append(right)
pair.sort(key=lambda x:len(x))







EE = [[0 for x in range(num+1)] for y in range(num+11)]
vis = [0] * (num+1)

for i in range(len(pair)): 
	EE[0][i+1] = 1
	EE[i+1][0] = 1

for i in range(n): 
	EE[i+101][num] = 1

for i in range(len(pair)): 
    for j in range(len(pair[i])):
        node1, node2 = i+1,pair[i][j]+101

        EE[node1][node2] = 1



flow=0
while 1:
    for i in range(0, num+1):
        vis[i] = 0
    if dfs(0) == 0:
        break
    flow += 1

print (flow)

Solution (Python):
n=int(input())
a=[]
b=[]
for i in range(n):
    a.append(list(map(int,input().split())))
for i in range(n):
    b.append(list(map(int,input().split())))
an=sorted(a, key=lambda x:-x[1])
bn=sorted(b)
count=0
for i in range(len(bn)):
    for j in range(len(an)):

        if bn[i][0]>an[j][0] and bn[i][1]>an[j][1]:
            count+=1
            an.pop(j)
            break
 
print(count)

Solution (Python):
N = int(input())
red = [3*N] * (2*N)
blue = [-1] * (2*N)
for i in range(N):
    a, b = (int(j) for j in input().split())
    red[a] = b
for i in range(N):
    a, b = (int(j) for j in input().split())
    blue[a] = b
ans = 0
for i in range(1, 2*N):
    for j in range(blue[i]-1, -1, -1):
        if j in red and red.index(j) < i:
            ans += 1
            blue[i] = 0
            red[red.index(j)] = 3 * N
            break
print(ans)

Solution (Python):
def friendly_pairs(red_points, blue_points):
    def can_be_friends(r, b):
        return r[0] < b[0] and r[1] < b[1]
    
    red = sorted(red_points, key=lambda x: (x[1], x[0]), reverse=True)
    blue = sorted(blue_points, key=lambda x: (x[0], x[1]))
    count = 0
    for b in blue:
        potential_friends = filter(lambda x: can_be_friends(x, b), red)
        if potential_friends:
            count += 1
            red.remove(potential_friends[0])
    return count


if __name__ == '__main__':
    n = int(raw_input())
    red_points = [map(int, raw_input().split())  for _ in xrange(n)]
    blue_points = [map(int, raw_input().split())  for _ in xrange(n)]
    print friendly_pairs(red_points, blue_points)

Solution (Python):
N = int(input())
R = []
for i in range(N):
    R.append(input().split())
    R[i].append(0)
R.sort(key=lambda x:(-int(x[1])))

B = []
for i in range(N):
    B.append(input().split())
    B[i].append(0)
B.sort(key=lambda x:(int(x[0]),int(x[1])))

a = 0
for i in range(N):
    for j in range(N):
        if int(R[j][0]) < int(B[i][0]) and int(R[j][1]) < int(B[i][1]) and R[j][2] == 0 and B[i][2] == 0:
            a += 1
            R[j][2] = j+1
            B[i][2] = j+1
            break

print(a)

Solution (Python):
N = int(input())
ab = [list(map(int, input().split())) for _ in range(N)]
cd = [list(map(int, input().split())) for _ in range(N)]

cd = sorted(cd, key=lambda x:x[0])
ab = sorted(ab, key=lambda x:x[1],reverse=True)


count = 0
i = 0
while i < N:
    for j in range(len(ab)):
        if cd[i][0] > ab[j][0] and cd[i][1] > ab[j][1]:
            count += 1
            del ab[j]
            break
    i += 1
print(count)

Solution (Python):
N = int(input())

L = []
for _ in range(N):
    p = [int(n) for n in input().split()]
    L.append((p[0], p[1], 'R'))

for _ in range(N):
    p = [int(n) for n in input().split()]
    L.append((p[0], p[1], 'B'))

L.sort(key=lambda x: x[0])

S = set()
for x, y, c in L:
    if c == 'R':
        S.add((x, y))
    else:
        SL = list(S)
        SL.sort(key=lambda x: x[1], reverse=True)
        SL = [s for s in SL if s[1] < y]
        if len(SL) > 0:
            S.remove(SL[0])

print(N - len(S))

Solution (Python):
n = int(input())
red = [list(map(int, input().split())) for i in range(n)]
red.sort(key=lambda x:x[1], reverse=True)
blue = [list(map(int, input().split())) for i in range(n)]
blue = sorted(blue)
ans = 0
for x_b, y_b in blue:
  for x_r, y_r in red:
    if x_r < x_b and y_r < y_b:
      red.remove([x_r, y_r])
      ans += 1
      break
print(ans)

Solution (Python):
import sys

stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline()

n = ni()
red = []
for _ in range(n):
    red.append(na())
blue = []
for _ in range(n):
    blue.append(na())

red.sort()
blue.sort()
ans = 0

tmp = []
for i in blue:
    for j in red:
        if i[0] > j[0] and i[1] > j[1]:
            tmp.append(j)
    if tmp != []:
        max_red = max(tmp, key=lambda x:x[1])
        ans += 1
        red.remove(max_red)
        tmp = []
    else:
        pass

print(ans)

Solution (Python):

N = int(input())

aka = []
for i in range(N):
    aka.append(list(map(int, input().split())))


ao = []
for i in range(N):
    ao.append(list(map(int, input().split())))


memo = [0 for i in range(N)]
memoB = [0 for i in range(N)]

_aka = sorted(aka, key=lambda x: x[0])
_ao = sorted(ao, key=lambda x: x[0])
ans = 0
for j in range(N):
    _i = -1
    _y = -1
    for i in range(N): 
        if _ao[j][0] > _aka[i][0] and _ao[j][1] > _aka[i][1] and memo[i] == 0:
            if _y < _aka[i][1]:
                _y = _aka[i][1]
                _i = i
    if not _i == -1:
        ans += 1
        memo[_i] = 1
        

print(ans)

Solution (Python):
N = int(input())
r = [list(map(int,input().split())) for _ in range(N)]
b = [list(map(int,input().split())) for _ in range(N)]
r.sort(key = lambda x:x[1],reverse = True)
b.sort(key = lambda x:x[0])
cnt = 0
fin = []
for i in range(N):
    for j in range(N):
        if b[i][0] > r[j][0] and b[i][1] > r[j][1]:
            if not(j in fin):
                cnt += 1
                fin.append(j)
                break
print(cnt)

Solution (Python):
n = int(input())

red = []
for i in range(n):
    red.append([int(j) for j in input().split()])
red.sort(key=lambda x : x[1], reverse=True)

blue = []
for i in range(n):
    blue.append([int(j) for j in input().split()])
blue.sort()

count = 0
for b in blue:
    for r in red:
        if r[0] < b[0] and r[1] < b[1]:
            count += 1
            red.remove(r)
            break
print(count)

Solution (Python):
red = list()
blue = list()
n = int(raw_input())

for i in range(0,n):
    red.append(map(int,raw_input().split()))
for i in range(0,n):
    blue.append(map(int, raw_input().split()))

red = sorted(red, key=lambda x:x[1], reverse=True)
blue = sorted(blue, key=lambda x:x[0])

c = int()
for r in red:
    for b in blue:
        if r[0]<b[0] and r[1]<b[1]:
            blue.remove(b)
            c+=1
            break
print c

Solution (Python):
from collections import deque


def main():
    """
    ab: red
    cd: blue

    仲良しペア: 最大で何個
        赤い点の x座標が青い点の x座標より小さい
        赤い点の y座標も青い点の y座標より小さい
        1つの点が複数のペアに所属することはできません。
    """
    N = int(input())

    ab = [
        tuple(map(int, input().split()))
        for _ in range(N)
    ]
    cd = [
        tuple(map(int, input().split()))
        for _ in range(N)
    ]

    f(N, ab, cd)


def f(N, ab, cd):
    """
    sortしてみたけどダメだった
        左下にある青
        右上にある赤
    N=100
    全ペア作ってみる: TLE
        ab/cdの全並べ方の組合せ
            ab permutation N!
            cd permutation N!
            N! * N!

    左下にある赤は価値が高い
    x座標の小さい青から始めているので, 赤x座標は青xより小さいものが対象
    y座標が高いものを選ぶのは
    選定中の赤座標と次の青と比較した時,
        次の青は今の青よりxは大きい
        つまり今y選定している赤のxより必ず大きいためどのx座標であるかは気にならない
        yが小さいものとペアにしたとき,とらなかったmax_yが次の青yより大きい可能性があるため
    """
    cd = deque(sorted(cd))

    used = [False] * N
    ans = 0
    while cd:
        c, d = cd.popleft()
        ai, ay = None, -1
        for i, (a, b) in enumerate(ab):
            if used[i]:
                continue
            if a < c and b < d:
                if b > ay:
                    ai, ay = i, b

        if ai is not None:
            
            used[ai] = True
            ans += 1

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
N=input()
a=[]
for i in range(2*N):
	x,y=map(int, raw_input().split())
	if i<N: a.append([x,y,"R"])
	else: a.append([x,y,"B"])

b=sorted(a, key=lambda x: x[0], reverse=True)


q=[]
ans=0
for i in b:
	x=i[1]
	type=i[2]
	if type=="B":
		q.append(x)
	elif type=="R" and len(q)>0:
		up=0
		tmp=[]
		for j in q:
			if x<=j:
				tmp.append(j)
				up=1
		ans+=up
		if len(tmp)>0:
			val=min(tmp)
			q.remove(val)

print ans

Solution (Python):
red = list()
blue = list()
n = int(raw_input())

for i in range(0,n):
    red.append(map(int,raw_input().split()))
for i in range(0,n):
    blue.append(map(int, raw_input().split()))

red = sorted(red, key=lambda x:x[1], reverse=True)
blue = sorted(blue, key=lambda x:x[0])

c = int()
for b in blue:
    for i,r in enumerate(red):
        if r[0]<b[0] and r[1]<b[1]:
            red.pop(i)
            c+=1
            break

print c

Solution (Python):
n = int(raw_input())

red = []
blue = []

for a in range(n):
  q = map(int,raw_input().split(" "))
  red.append(q)

for a in range(n):
  q = map(int,raw_input().split(" "))
  blue.append(q)

red.sort()
blue.sort()
G = []
for a in range(n*2):
  G.append([])

used = [0]*(n*2)
match = [-1]*(n*2)

def add_edge(u,v):
  global G
  G[u].append(v)
  G[v].append(u)

def dfs(v):
  global G,match,used
  used[v] = 1
  for i in range( len(G[v]) ):
    u = G[v][i]
    w = match[u]
    if w < 0 or (used[w] != 1) and dfs(w) == 1:
      match[v] = u
      match[u] = v
      return 1
  return 0

for a in range(n):
  for b in range(n):
    if red[a][0] < blue[b][0] and red[a][1] < blue[b][1]:
      add_edge(a,b+n)

ans = 0
for a in range(n):
  if match[a] < 0:
    used = [0]*n
    if dfs(a) == 1:
      ans += 1
print ans

Solution (Python):
n=int(input())
red=[0]*n
for i in range(n):
    a,b=map(int,input().split())
    red[i]=(a,b)
blue=[0]*n
for i in range(n):
    a,b=map(int,input().split())
    blue[i]=(a,b)
blue.sort()
c=0
for bx,by in blue:
    maxry=-1
    maxi=-1
    for i in range(len(red)):
        rx,ry=red[i]
        if rx < bx and ry < by:
            if maxry < ry:
                maxry=ry
                maxi=i
    if not maxi == -1:
        c+=1
        red.pop(maxi)
print(c)

Solution (Python):

n = int(input())

red_array = []
for i in range(n):
    red_array.append([int(x) for x in input().split()])
red_array = sorted(red_array, key=lambda x: x[1], reverse=True)

blue_array = []
for i in range(n):
    blue_array.append([int(x) for x in input().split()])
blue_array.sort()

for blue in blue_array:
    for red in red_array:
        if blue[0] > red[0] and blue[1] > red[1]:
            red_array.remove(red)
            break

print(n - len(red_array))

Solution (Python):
from pprint import pprint
N = int(input())
reds = []
for i in range(N):
    reds.append(tuple(map(int, input().split(" "))))
blues = []
for i in range(N):
    blues.append(tuple(map(int, input().split(" "))))
reds.sort(key=lambda x: (x[1], x[0]), reverse=True)
blues.sort()
picked = [False for _ in range(N)]
ans = 0
for blue in blues:
    for i, red in enumerate(reds):
        if blue[0] > red[0] and blue[1] > red[1] and not picked[i]:
            ans += 1
            picked[i] = True
            break
print(ans)

Solution (Python):
if __name__ == "__main__":


















































    N = int(input())
    R = [list(map(int, input().split(" "))) for _ in range(N)]
    B = [list(map(int, input().split(" "))) for _ in range(N)]
    R.sort(key=lambda x: (x[1], x[0]), reverse=True)
    B.sort(key=lambda x: (x[0], x[1]))
    f = [0] * N

    pair = 0
    for b in B:
        for i, r in enumerate(R):
            if r[0] < b[0] and r[1] < b[1] and f[i] == 0:
                pair += 1
                f[i] = 1
                break

    print(pair)

Solution (Python):
from math import sqrt

N = int(input())

reds = sorted([list(map(int, input().split(' '))) for i in range(N)])
blues = sorted([list(map(int, input().split(' '))) for i in range(N)], key = lambda x: x[0])

result = 0

for i in range(N):
    max_dis = -1
    tmp_index = -1
    length = len(reds)
    for j in range(length):
        if blues[i][0] > reds[j][0] and blues[i][1] > reds[j][1]:
            dis = reds[j][1]
            if max_dis < dis:
                max_dis = dis
                tmp_index = j
    if tmp_index != -1:
        result += 1
        reds.pop(tmp_index)

print(result)

Solution (Python):
def c_2D_plane_2N_points(N, R, B):
    red = sorted(R)  
    blue = sorted(B)  
    ans = 0
    for c, d in blue:
        
        r = [z for z in red if z[0] < c and z[1] < d]
        if r:  
            r.sort(key=lambda x: x[1])  
            
            
            
            red.remove(r[-1])  
            ans += 1
    return ans
N = int(input())
R = [[int(i) for i in input().split()] for j in range(N)]
B = [[int(i) for i in input().split()] for j in range(N)]
print(c_2D_plane_2N_points(N, R, B))

Solution (Python):
if __name__ == '__main__':
    N = int(input().strip())
    lines = [input().split() for _ in range(N)]
    ab = [(int(line[0]), int(line[1])) for line in lines]
    lines = [input().split() for _ in range(N)]
    cd = [(int(line[0]), int(line[1])) for line in lines]

    candidates = []
    count = 0

    points = sorted(ab + cd, key=lambda x: x[0])
    for p in points:
        if p in ab:
            candidates.append(p)
            candidates = sorted(candidates, key=lambda x: x[1], reverse=True)
        else:
            
            
            
            for i, cand in enumerate(candidates):
                if cand[1] < p[1]:
                    count += 1
                    candidates.pop(i)
                    break

    print(count)

Solution (Python):
N = int(input())
AB = [tuple(int(_) for _ in input().split()) for i in range(N)]
CD = [tuple(int(_) for _ in input().split()) for i in range(N)]

AB.sort(key=lambda xy:xy[1], reverse=True)
CD.sort()
for c, d in CD:
    for a, b in AB:
        if a < c and b < d:
            AB.remove((a, b))
            break

print(N - len(AB))

Solution (Python):
n = int(raw_input())

red = []
blue = []
data = []

for a in range(n):
  q = map(int,raw_input().split(" "))
  red.append(q)
  data.append(q)

for a in range(n):
  q = map(int,raw_input().split(" "))
  blue.append(q)
  data.append(q)

red.sort()
blue.sort()
data.sort()

s = []
ans = 0

for a in data:
  if a in red:
    s.append(a)
  else:
    q = None
    y = -1
    for b in s:
      if y < b[1] and b[1] < a[1]:
        q = b
        y = b[1]
    if q != None:
      s.remove(q)
      ans += 1

print ans

Solution (Python):
N = int(input())
R = [list(map(int, input().split())) for i in range(N)]
B = [list(map(int, input().split())) for i in range(N)]
B = sorted(B, key = lambda x:x[0])
ans = 0
for b in B:
    tmp = -1
    rp = -1
    for i, r in enumerate(R):
        if b[0] > r[0] and b[1] > r[1]:
            if r[1] > tmp:
                tmp = r[1]
                rp = i
    if rp >= 0:
        R.pop(rp)
        ans += 1
print(ans)

Solution (Python):
n = int(input().strip())
ab = [list(map(int, input().strip().split(" "))) for _ in range(n)]
cd = [list(map(int, input().strip().split(" "))) for _ in range(n)]

candidate = []
ans = 0
ps = sorted(ab + cd, key=lambda x: x[0])
for p in ps:
    if p in ab:
        candidate.append(p)
        candidate = sorted(candidate, key=lambda x: x[1], reverse=True)
    else:
        for i, _p in enumerate(candidate):
            if _p[1] < p[1]:
                ans += 1
                candidate.pop(i)
                break
print(ans)

Solution (Python):

from collections import deque
N = int(input())
red = []
for i in range(N):
    red.append(list(map(int, input().split(' '))))
blue = []
for i in range(N):
    blue.append(list(map(int, input().split(' '))))
red = deque(sorted(red, key=lambda x:(x[1], x[0]), reverse=True))
blue = deque(sorted(blue))
count = 0
flag = [0] * N
for b in blue:
    for i, r in enumerate(red):
        if r[0] < b[0] and r[1] < b[1] and flag[i] == 0:
            count += 1
            flag[i] = 1
            break

print(count)

Solution (Python):
class Graph:
    def __init__(self, graph):
        self.graph = graph 
        self.part_1 = len(graph)
        self.part_2 = len(graph[0])
    
    
    def bpm(self, u, matchR, visited):
        for v in range(self.part_2):
            if self.graph[u][v] and visited[v] == False:
                visited[v] = True
                if matchR[v] == -1 or self.bpm(matchR[v], matchR, visited):
                    matchR[v] = u
                    return True
        return False

    
    def maxBPM(self):
        matchR = [-1] * self.part_2
        result = 0
        for i in range(self.part_1):
            visited = [False] * self.part_2
            if self.bpm(i, matchR, visited):
                result += 1
        return result

N = int(input())
reds = [tuple(map(int, input().split())) for _ in range(N)]
blues = [tuple(map(int, input().split())) for _ in range(N)]

edges = [[0 for _ in range(N)] for _ in range(N)]

for i in range(N):
    for j in range(N):
        if reds[i][0] < blues[j][0] and reds[i][1] < blues[j][1]:
            edges[i][j] = 1

g = Graph(edges)

print(g.maxBPM())

Solution (Python):
N = int(input())
red = [3*N] * (2*N)
blue = [-1] * (2*N)
for i in range(N):
    a, b = (int(j) for j in input().split())
    red[a] = b
for i in range(N):
    a, b = (int(j) for j in input().split())
    blue[a] = b
ans = 0
for i in range(1, 2*N):
    for j in range(blue[i]-1, -1, -1):
        if j in red and red.index(j) < i:
            ans += 1
            blue[i] = 0
            red[red.index(j)] = 3 * N
            break
print(ans)

Solution (Python):

from collections import deque

N = int(input())
R = [list(map(int, input().split(" "))) for _ in range(N)]
B = [list(map(int, input().split(" "))) for _ in range(N)]
R.sort(key=lambda x:(x[1],x[0]), reverse=True)
B.sort(key=lambda x:(x[0],x[1]))
R = deque(R)
B = deque(B)
f = [0]*N

pair = 0
for b in B:
    for i, r in enumerate(R):
        if r[0]<b[0] and r[1]<b[1] and f[i] == 0:
            pair += 1
            f[i] = 1
            break
    
print(pair)

Solution (Python):
N = int(input())

a, b = [], []
for n in range(N):
    _a, _b = map(int, input().split(' '))
    a.append(_a)
    b.append(_b)

c, d = [], []
for n in range(N):
    _c, _d = map(int, input().split(' '))
    c.append(_c)
    d.append(_d)

def dfs(v, visited):
    """
    :param v: X側の未マッチングの頂点の1つ
    :param visited: 空のsetを渡す（外部からの呼び出し時）
    :return: 増大路が見つかればTrue
    """
    for u in edges[v]:
        if u in visited:
            continue
        visited.add(u)
        if matched[u] == -1 or dfs(matched[u], visited):
            matched[u] = v
            return True
    return False


edges = [set() for _ in range(N)]
matched = [-1] * N


M = [[0 for _ in range(N)] for _ in range(N)]
for i in range(N):
    for j in range(N):
        if a[i] < c[j] and b[i] < d[j]:
            edges[i].add(j)


print(sum(dfs(s, set()) for s in range(N)))

Solution (Python):
from collections import defaultdict
n = int(input())
G = defaultdict(list)
rec = []
for i in range(n):
    a, b = map(int, input().split())
    rec.append((i, a, b))


for i in range(n):
    c, d = map(int, input().split())
    for index, p, q in rec:
        if p < c and q < d:
            G[index].append(i + n)
            G[i + n].append(index)


used = [False] * 2 * n
match = [-1] * 2 * n


def dfs(v):
    global used
    used[v] = True
    for u in G[v]:
        w = match[u]
        if w < 0 or not used[w] and dfs(w):
            match[v] = u
            match[u] = v
            return True


ma = 0
for i in range(n):
    if match[i] < 0:
        used = [False] * 2 * n
        if dfs(i):
            ma += 1

print(ma)