Problem:


Score : 500 points

Problem Statement

We have a two-dimensional grid with H \times W squares. There are M targets to destroy in this grid - the position of the i-th target is \left(h_i, w_i \right).

Takahashi will choose one square in this grid, place a bomb there, and ignite it. The bomb will destroy all targets that are in the row or the column where the bomb is placed. It is possible to place the bomb at a square with a target.

Takahashi is trying to maximize the number of targets to destroy. Find the maximum number of targets that can be destroyed.

Constraints

All values in input are integers.

1 \leq H, W \leq 3 \times 10^5

1 \leq M \leq \min\left(H\times W, 3 \times 10^5\right)

1 \leq h_i \leq H

1 \leq w_i \leq W

\left(h_i, w_i\right) \neq \left(h_j, w_j\right) \left(i \neq j\right)

Input

Input is given from Standard Input in the following format:

H W M
h_1 w_1
\vdots
h_M w_M

Output

Print the answer.

Sample Input 1

2 3 3
2 2
1 1
1 3

Sample Output 1

3

We can destroy all the targets by placing the bomb at \left(1, 2\right).

Sample Input 2

3 3 4
3 3
3 1
1 1
1 2

Sample Output 2

3

Sample Input 3

5 5 10
2 5
4 3
2 3
5 5
2 2
5 4
5 3
5 1
3 5
1 4

Sample Output 3

6



Sample input:
2 3 3
2 2
1 1
1 3


Sample output:
3

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import heapq

def main():
    H, W, M = map(int, readline().split())
    m = map(int,read().split())
    hw = list(zip(m,m))

    row_bombers = [0] * (H+1)
    col_bombers = [0] * (W+1)

    for (h, w) in hw:
        row_bombers[h] += 1
        col_bombers[w] += 1

    row_max = max(row_bombers)
    col_max = max(col_bombers)

    max_rows = [i for i in range(H+1) if row_bombers[i] == row_max]
    max_cols = [i for i in range(W+1) if col_bombers[i] == col_max]

    ans = row_max + col_max
    
    num_empty_cells_in_kouho = len(max_rows) * len(max_cols)
    for (h, w) in hw:
        if row_bombers[h] == row_max and col_bombers[w] == col_max:
            num_empty_cells_in_kouho -= 1

    if num_empty_cells_in_kouho == 0:
        ans -= 1
    
    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
h, w, m = map(int, input().split())
H = [0] * (h+1)
W = [0] * (w+1)
bombs = set()
for _ in range(m):
    hh, ww = map(lambda x: int(x)-1, input().split())
    H[hh] += 1
    W[ww] += 1
    bombs.add((hh, ww))

mh = max(H)
mw = max(W)
mhis = [i for i, x in enumerate(H) if x == mh]
mwis = [i for i, x in enumerate(W) if x == mw]

duplicated = True
for mhi in mhis:
    for mwi in mwis:
        if not (mhi, mwi) in bombs:
            duplicated = False
            break
            
ans = mh + mw - duplicated
print(ans)

Submission status: Accepted

Solution code:
import sys,bisect

from sys  import stdin,stdout

from bisect import bisect_left,bisect_right,bisect,insort,insort_left,insort_right

from math import gcd,ceil,floor,sqrt

from collections import Counter,defaultdict,deque,OrderedDict

from queue import Queue,PriorityQueue

from string import ascii_lowercase

sys.setrecursionlimit(10**6)
INF = float('inf')
MOD = 998244353
mod = 10**9+7

def isPrime(n):
    
    if (n <= 1) :return False
    if (n <= 3) :return True
    if (n%2 == 0 or n%3 == 0):return False
    for i in range(5,ceil(sqrt(n))+1,6):
        if (n%i==0 or n%(i+2)==0):
            return False
    return True


def st():
    return list(stdin.readline().strip())

def inp():
    return int(stdin.readline())

def li():
    return list(map(int,stdin.readline().split()))

def mp():
    return map(int,stdin.readline().split())

def pr(n):
    stdout.write(str(n)+"\n")
    
def DFS(dictionary,vertex,visited):
    visited[vertex]=True
    stack=[vertex]
    print(vertex)
    while stack:
        a=stack.pop()
        for i in dictionary[a]:
            if not visited[i]:
                print(i)
                visited[i]=True
                stack.append(i)


def BFS(dictionary, vertex,visited):
    visited[vertex]=True
    q=deque()
    q.append(vertex)
    while q:
        a=q.popleft()
        for i in dictionary[a]:
            if not visited[i]:
                visited[i]=True
                q.append(i)
                print(i)

                


def soe(limit):
    l=[1]*(limit+1)
    l[0]=0
    l[1]=0
    prime=[]
    for i in range(2,limit+1):
        if l[i]:
            for j in range(i*i,limit+1,i):
                l[j]=0
    
    for i in range(2,limit+1):
        if l[i]:
            prime.append(i)
    return prime

def segsoe(low,high):
    limit=int(high**0.5)+1
    prime=soe(limit)
    n=high-low+1
    l=[0]*(n+1)
    for i in range(len(prime)):
        lowlimit=(low//prime[i])*prime[i]
        if lowlimit<low:
            lowlimit+=prime[i]
        if lowlimit==prime[i]:
            lowlimit+=prime[i]
        for j in range(lowlimit,high+1,prime[i]):
            l[j-low]=1
    for i in range(low,high+1):
        if not l[i-low]:
            if i!=1:
                print(i)
                
def gcd(a,b):
    while b:
        a=a%b
        b,a=a,b
    return a

def power(a,n):
    r=1
    while n:
        if n&1:
            r=(r*a)
        a*=a
        n=n>>1
    return r
    
def solve():
    r,c,m=mp()
    row={}
    col={}
    dd={}
    d={}
    for i in range(m):
        l=li()
        a=l[0]
        b=l[1]
        row[a]=row.get(a,0)+1
        col[b]=col.get(b,0)+1
    
        if a in d:
            d[a].add(b)
        else:
            d[a]={b}

        if b in dd:
            dd[b].add(a)
        else:
            dd[b]={a}
    
    miR,miC=float('-inf'),float('-inf')
    
    for i in row:
        if row[i]>miR:
            miR=row[i]
            R=i
    for i in col:
        if col[i]>miC:
            miC=col[i]
            C=i

    ans=float('-inf')

    for i in col:
        c=miR+col[i]
        if i in d[R]:
            c-=1
        ans=max(ans,c)

    for  i in row:
        c=miC+row[i]
        if i in dd[C]:
            c-=1
        ans=max(ans,c)

    pr(ans)
        
        
        
            

for _ in range(1):
    solve()

Submission status: Accepted

Solution code:
H, W, M = map(int, input().split())
hw = [list(map(int, input().split())) for _ in range(M)]

h_cnt = [0] * (H + 1)
w_cnt = [0] * (W + 1)

for h, w in hw:
    h_cnt[h] += 1
    w_cnt[w] += 1

h_mx = max(h_cnt)
w_mx = max(w_cnt)

cnt = h_cnt.count(h_mx) * w_cnt.count(w_mx)
for h, w in hw:
    val = h_cnt[h] + w_cnt[w]
    if val == h_mx + w_mx:
        cnt -= 1

if cnt:
    ans = h_mx + w_mx
else:
    ans = h_mx + w_mx - 1

print(ans)

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline

def solve():
    H, W, M = map(int, input().split())
    numRs = [0] * H
    numCs = [0] * W
    hws = []
    for _ in range(M):
        h, w = map(int, input().split())
        h, w = h-1, w-1
        numRs[h] += 1
        numCs[w] += 1
        hws.append((h, w))

    maxR = max(numRs)
    maxC = max(numCs)

    hs = set()
    ws = set()
    for h in range(H):
        if numRs[h] == maxR:
            hs.add(h)
    for w in range(W):
        if numCs[w] == maxC:
            ws.add(w)
    numH = len(hs)
    numW = len(ws)

    num = 0
    for hb, wb in hws:
        if hb in hs and wb in ws:
            num += 1

    ans = maxR+maxC
    if num == numH*numW:
        ans -= 1

    print(ans)


solve()

Submission status: Accepted

Solution code:
h, w, m = map(int, input().split())
s = dict()
num_h = [0] * h
num_w = [0] * w
for _ in range(m):
    hi, wi = map(int, input().split())
    hi -= 1
    wi -= 1
    s[(hi, wi)] = True
    num_h[hi] += 1
    num_w[wi] += 1
max_h_list = []
max_h_val = 0
max_w_list = []
max_w_val = 0
for hi in range(h):
    if num_h[hi] > max_h_val:
        max_h_list = [hi]
        max_h_val = num_h[hi]
    elif num_h[hi] == max_h_val:
        max_h_list.append(hi)
for wi in range(w):
    if num_w[wi] > max_w_val:
        max_w_list = [wi]
        max_w_val = num_w[wi]
    elif num_w[wi] == max_w_val:
        max_w_list.append(wi)

if len(max_h_list) * len(max_w_list) > m:
    print(max_h_val + max_w_val)
    exit()
for max_hi in max_h_list:
    for max_wi in max_w_list:
        if s.get((max_hi, max_wi), False) == False:
            print(max_h_val + max_w_val)
            exit()
print(max_h_val + max_w_val - 1)

Submission status: Accepted

Solution code:
import sys
 
input = sys.stdin.readline
 
 
def main():
    H, W, M = map(int, input().split())
    row = [0] * (H)
    col = [0] * (W)
    bomb = set()
    for _ in range(M):
        h, w = map(int, input().split())
        bomb.add((h, w))
        row[h-1] += 1
        col[w-1] += 1
    row_max = max(row)
    row_index_list = [i for i, v in enumerate(row) if v == row_max]
    col_max = max(col)
    col_index_list = [i for i, v in enumerate(col) if v == col_max]
    ans = row_max + col_max - 1
    c = False
    for x in row_index_list:
        for y in col_index_list:
            if not (x + 1, y + 1) in bomb:
                c = True
                break
        if c:
            break
    if c:
        ans += 1
    print(ans)
 
 
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import numpy as np

H, W, M = map(int, input().split())
h_t = [0]*H
w_t = [0]*W
t = {}
for i in range(M):
    h, w = map(int, input().split())
    t[(h-1, w-1)] = 1
    h_t[h-1]+=1
    w_t[w-1]+=1
h_max = max(h_t)
h_max_list = [i for i in range(len(h_t)) if h_t[i] == h_max]
w_max = max(w_t)
w_max_list = [i for i in range(len(w_t)) if w_t[i] == w_max]

for h in h_max_list:
    for w in w_max_list:
        if (h, w) not in t:
            print(h_max + w_max)
            exit()
print(h_max + w_max - 1)

Submission status: Accepted

Solution code:
from collections import deque

h,w,m = map(int,input().split())
Ms = []

h_scores = [0 for i in range(h)]
w_scores = [0 for i in range(w)]

record = set()

for i in range(m):
  h,w = map(int,input().split())
  record.add((h-1,w-1))
  h_scores[h-1] += 1
  w_scores[w-1] += 1

max_h = max(h_scores)
max_w = max(w_scores)
max_h_poss = [i for i,v in enumerate(h_scores) if v == max_h]
max_w_poss = [i for i,v in enumerate(w_scores) if v == max_w]

out_pos_count = 0 

c = False

for i in max_h_poss:
    for j in max_w_poss:
        if (i,j) not in record:
            c = True
            break        

if c:
    print(max(h_scores) + max(w_scores))
else:
    print(max(h_scores) + max(w_scores)-1)

Submission status: Accepted

Solution code:
H, W, M = map(int, input().split())
bom = set()
row = [0] * H
col = [0] * W

for _ in range(M):
    h, w = map(int, input().split())
    bom.add((h-1, w-1))
    row[h-1] += 1
    col[w-1] += 1

max_row = max(row)
max_col = max(col)
ans = max_row + max_col - 1

p, q = [], []

for i in range(H):
    if row[i] == max_row:
        p.append(i)

for j in range(W):
    if col[j] == max_col:
        q.append(j)

flag = False
for i in p:
    for j in q:
        if (i, j) not in bom:
            ans += 1
            flag = True
            break
    if flag:
        break

print(ans)

Submission status: Accepted

Solution code:
h, w, m = map(int, input().split())
h_cnt = [0] * h
w_cnt = [0] * w

bomb_set = set()

for i in range(m):
    h_, w_ = map(int, input().split())
    h_ -= 1
    w_ -= 1
    h_cnt[h_] += 1
    w_cnt[w_] += 1
    bomb_set.add((h_, w_))

max_h = max(h_cnt)
max_h_idx = []
for i in range(h):
    if h_cnt[i] == max_h:
        max_h_idx.append(i)

max_w = max(w_cnt)
max_w_idx = []
for i in range(w):
    if w_cnt[i] == max_w:
        max_w_idx.append(i)

minus = -1
for i in max_h_idx:
    for j in max_w_idx:
        if (i, j) not in bomb_set:
            print(max_h + max_w)
            exit()
print(max_h + max_w - 1)

Submission status: Accepted

Solution code:
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

h, w, m = LI()
bomb = defaultdict(lambda : 0)
cnt_h = [0] * h
cnt_w = [0] * w
for _ in range(m):
    H, W = LI()
    bomb[(H-1, W-1)] = 1
    cnt_h[H-1] += 1
    cnt_w[W-1] += 1

m_h = max(cnt_h)
m_w = max(cnt_w)
H_l = []
W_l = []
for i in range(h):
    if cnt_h[i] == m_h:
        H_l.append(i)

for i in range(w):
    if cnt_w[i] == m_w:
        W_l.append(i)

ans = m_h + m_w

for i in H_l:
    for j in W_l:
        if not bomb[(i, j)]:
            print(ans)
            quit()
print(ans-1)

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float("INF")

#solve
def solve():
    h,w,m = LI()
    hw = LIR(m)
    # h, w, m = [3 * 10 ** 5] * 3
    # hw = [(i, i) for i in range(3 * 10 ** 5)]
    dh = defaultdict(int)
    dh1 = defaultdict(int)
    dw = defaultdict(int)
    dw1 = defaultdict(int)
    ma = defaultdict(int)
    for hi, wi in hw:
        dh[hi] += 1
        dw[wi] += 1
        ma[(hi, wi)] = 1
    maxh = max(dh.values())
    maxw = max(dw.values())
    for key, value in dh.items():
        if value == maxh:
            dh1[key] = maxh
    for key, value in dw.items():
        if value == maxw:
            dw1[key] = maxw
    for kh, vh in dh1.items():
        for kw, vw in dw1.items():
            if ma[(kh, kw)] == 0:
                print(vh + vw)
                return
    print(vh + vw - 1)
    
    return


#main
if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
H, W, M = map(int, input().split())
hw = [list(map(int, input().split())) for _ in range(M)]

h_count = {}
w_count = {}
for h,w in hw:
    if h in h_count:
        h_count[h] += 1
    else:
        h_count[h] = 1
    if w in w_count:
        w_count[w] += 1
    else:
        w_count[w] = 1

max_h = max(h_count.values())
max_w = max(w_count.values())
ans = max_h + max_w

max_h_list = set([k for k,v in h_count.items() if v == max_h])
max_w_list = set([k for k,v in w_count.items() if v == max_w])

num = 0
for h,w in hw:
    if h in max_h_list and w in max_w_list:
        num += 1

if num < len(max_h_list)*len(max_w_list):
    print(ans)
else:
    print(ans-1)

Submission status: Accepted

Solution code:
H, W, M = map(int, input().split())

B = [list(map(int, input().split())) for _ in range(M)]

bombs_row = [0] * H
bombs_col = [0] * W

for b in B:
    bombs_row[b[0] - 1] += 1
    bombs_col[b[1] - 1] += 1

row_max = max(bombs_row)
col_max = max(bombs_col)

row_max_count = bombs_row.count(row_max)
col_max_count = bombs_col.count(col_max)

ans = row_max + col_max

possible_point = row_max_count * col_max_count

bombed_point = 0

for b in B:
    if bombs_row[b[0] - 1] == row_max and bombs_col[b[1] - 1] == col_max:
        bombed_point += 1

if bombed_point == possible_point:
    ans -= 1

print(ans)

Submission status: Accepted

Solution code:
import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    H, W, M = LI()
    hw = {tuple(LI()) for _ in range(M)}

    cnt_h = collections.Counter([h for h, w in hw])
    cnt_w = collections.Counter([w for h, w in hw])

    max_h = max(cnt_h.values())
    max_w = max(cnt_w.values())
    max_h_k = [k for k, v in cnt_h.items() if v == max_h]
    max_w_k = [k for k, v in cnt_w.items() if v == max_w]

    # 縦横のターゲット数最大の座標に置く
    # そのような座標がターゲット上ならば、縦横ターゲット数から1を引く
    is_on_target = True
    for i, j in itertools.product(max_h_k, max_w_k):
        if (i, j) not in hw:
            is_on_target = False
            break

    if is_on_target:
        ans = max_h + max_w - 1
    else:
        ans = max_h + max_w
    print(ans)

if __name__ == '__main__':
    resolve()

Submission status: Accepted

Solution code:
# coding: utf-8
# Your code here!
# 幅優先探索（行きがけ）
import collections
import sys
import copy
import re
import math
import itertools


def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int, sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())


def main():
    H, W, M = LI()

    HList = [0]*H
    WList = [0]*W
    graph = set()
    for m in range(M):
        h, w = LI()
        HList[h-1] += 1
        WList[w-1] += 1
        graph.add((h-1, w-1))

    Hmax = max(HList)
    Wmax = max(WList)

    HIndex = [i for i, v in enumerate(HList) if v == Hmax]
    WIndex = [i for i, v in enumerate(WList) if v == Wmax]

    ans = Hmax + Wmax
    for h in HIndex:
        for w in WIndex:
            if not (h, w) in graph:
                print(ans)
                return

    print(ans-1)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
from collections import defaultdict
H, W, M = map(int, input().split())
rows = {i: 0 for i in range(H)}
cols = {i: 0 for i in range(W)}
d = defaultdict(int)
for _ in range(M):
    h, w = map(int, input().split())
    h -= 1
    w -= 1
    rows[h] += 1
    cols[w] += 1
    d[(h,w)] += 1
mr = max(rows.values())
mc = max(cols.values())
max_rows = [kv for kv in rows.items() if kv[1] == mr]
max_cols = [kv for kv in cols.items() if kv[1] == mc]
non_dup = False
ans = max_rows[0][1] + max_cols[0][1]
flg = False
for kh, vh in max_rows:
    for kw, vw in max_cols:
        if d[(kh, kw)] == 0:
            non_dup = True
            flg = True
            break
    if flg:
        break
if not non_dup:
    ans -= 1
print(ans)

Submission status: Accepted

Solution code:
h,w,m = list(map(int,input().split()))
t = [list(map(int,input().split())) for _ in range(m)]
from collections import Counter
 
x,y = zip(*t)

xcnt = Counter(x)
ycnt = Counter(y)
 
xcmax = max( xcnt.values() )
ycmax = max( ycnt.values() )
xlist = [k for k,v in xcnt.items() if v == xcmax]
ylist = [k for k,v in ycnt.items() if v == ycmax]
if len(xlist) * len(ylist) > m:
  print( xcmax + ycmax )
else:
  xylist = { i*(10**6)+j for i in xlist for j in ylist }
  tlist = { i[0]*(10**6) + i[1] for i in t }
  if len( xylist - tlist ) == 0:
    print( xcmax + ycmax -1 )
  else:
    print( xcmax + ycmax )

Submission status: Accepted

Solution code:

#!/usr/bin/python
# -*- coding: utf-8 -*-

# def
def int_mtx(N):
    x = []
    for _ in range(N):
        x.append(list(map(int,input().split())))
    return x

def str_mtx(N):
    x = []
    for _ in range(N):
        x.append(list(input()))
    return x

def int_map():
    return map(int,input().split())

def int_list():
    return list(map(int,input().split()))

def print_space(l):
    return print(" ".join([str(x) for x in l]))

# import
import numpy as np
import statistics
import math
import collections

# main code
H,W,M = int_map()
hw = int_mtx(M)

h = []
w = []
for hhww in hw:
    h.append(hhww[0])
    w.append(hhww[1])

ch = collections.Counter(h)
cw = collections.Counter(w)
a = ch.most_common()[0][1]
b = cw.most_common()[0][1]

if a == M or b == M:
    print(M)
    exit()

if a < b:
    bb = cw.most_common()[0][0]
    hw1 = [i for i in hw if not i[1] == bb]
    
    h1 = []
    for hhww in hw1:
        h1.append(hhww[0])

    ch1 = collections.Counter(h1)
    a1 = ch1.most_common()[0][1]

    print(b+a1)
    exit()
else:
    aa = ch.most_common()[0][0]
    hw1 = [i for i in hw if not i[0] == aa]
    
    w1 = []
    for hhww in hw1:
        w1.append(hhww[1])

    cw1 = collections.Counter(w1)
    b1 = cw1.most_common()[0][1]

    print(a+b1)
    exit()

Submission status: Accepted

Solution code:
H,W,M = map(int,input().split())
T = [0] * M
H_cnt = {}
W_cnt = {}
HW = {}
for i in range(M):
    h,w = map(int,input().split())
    if not h in H_cnt:
        H_cnt[h] = 0
    if not w in W_cnt:
        W_cnt[w] = 0
    H_cnt[h] += 1
    W_cnt[w] += 1
    HW[(h,w)] = 1

HL = [[h,cnt] for h,cnt in H_cnt.items()]
WL = [[w,cnt] for w,cnt in W_cnt.items()]

HL.sort(key=lambda x: x[1],reverse=True)
WL.sort(key=lambda x: x[1],reverse=True)

HS = {}
max_cnth = 0
for h,cnt in HL:
    if max_cnth<=cnt:
        HS[h] = cnt
        max_cnth = max(max_cnth,cnt)
        continue
    break

WS = {}
max_cntw = 0
for w,cnt in WL:
    if max_cntw<=cnt:
        WS[w] = cnt
        max_cntw = max(max_cntw,cnt)
        continue
    break

cnt = 0
ans = 0

# ここの判定を高速にする
cross_cnt = 0
for hw in HW.keys():
    h,w = hw
    if h in HS and w in WS:
        cross_cnt+=1
if len(WS) * len(HS)==cross_cnt:
    print(max_cnth+max_cntw-1)
    exit()
print(max_cnth+max_cntw)

Submission status: Accepted

Solution code:
h,w,m = map(int, input().split())

lh = []
lw = []

for i in range(m):
  h1,w1 = map(int, input().split())
  lh.append(h1)
  lw.append(w1)

if h == 1 or w == 1:
  print(m)
else:
  from collections import Counter as co
  ch=co(lh).most_common()
  cw=co(lw).most_common()
  
  ans = 0
  tmp = ch[0][0]
  lh_c = [i for i, x in enumerate(lh) if x == tmp]
  lw_tmp = lw[:]
  for j in sorted(lh_c, reverse=True):
    lw_tmp.pop(j)
  if len(lw_tmp) == 0:
    print(ch[0][1])
  else:
    cw_tmp = co(lw_tmp).most_common()
    ans = ch[0][1]+cw_tmp[0][1]
    
    tmp = cw[0][0]
    lw_c = [i for i, x in enumerate(lw) if x == tmp]
    lh_tmp = lh[:]
    for j in sorted(lw_c, reverse=True):
      lh_tmp.pop(j)
    if len(lh_tmp) == 0:
      print(cw[0][1])
    else:
      ch_tmp = co(lh_tmp).most_common()
      ans = max(ans, cw[0][1]+ch_tmp[0][1])
      print(ans)

Submission status: Accepted

Solution code:
import math
from functools import reduce
from collections import deque
import sys
sys.setrecursionlimit(10**7)
from bisect import bisect_left
def input():
    return sys.stdin.readline().strip()

# スペース区切りの入力を読み込んで数値リストにして返します。
def get_nums_l():
    return [ int(s) for s in input().split(" ")]

# 改行またはスペース区切りの入力をすべて読み込んでイテレータを返します。
def get_all_int():
    return map(int, open(0).read().split())

def log(*args):
    print("DEBUG:", *args, file=sys.stderr)

def main():
    INF = 999999999999999999999999
    MOD = 10**9+7

    h,w,m = get_nums_l()
    targets = []
    H = []
    W = []
    HW = []
    for i in range(m):
        hi, wi = get_nums_l()
        HW.append((hi-1, wi-1))
        H.append(hi-1)
        W.append(wi-1)

    HW.sort()
    
    rows = [0] * h
    cols = [0] * w

    for i in range(m):
        rows[H[i]] += 1
        cols[W[i]] += 1

    rmax = 0
    rmaxi = []
    for i,x in enumerate(rows):
        if x > rmax:
            rmax = x
            rmaxi = [i]
        elif x == rmax:
            rmaxi.append(i)
    cmax = 0
    cmaxi = []
    for i,x in enumerate(cols):
        if x > cmax:
            cmax = x
            cmaxi = [i]
        elif x == cmax:
            cmaxi.append(i)

    # log(rmax,cmax)
    # log(rmaxi, cmaxi)

    for rmi in rmaxi:
        for cmi in cmaxi:
            ok = True
            i = bisect_left(HW, (rmi, cmi))
            if i<m and HW[i] == (rmi, cmi):
                ok = False
            # for i in range(m):
            #     if H[i] == rmi and W[i] == cmi:
            #         ok = False
            #         break
            if ok:
                print(rmax + cmax)
                return

    print(rmax + cmax - 1)

main()

Submission status: Accepted

Solution code:
from sys import exit, stdin

# import copy
from collections import deque, Counter

# import numpy as np
input = stdin.readline

H, W, M = map(int, input().split())

col = Counter()
row = Counter()
D = Counter()
for i in range(M):
    h, w = map(int, input().split())
    row.update([h])
    col.update([w])
    D.update([str(h) + str(w)])

# rmax = row.most_common(1)
# cmax = col.most_common(1)
# idx = str(rmax[0][0]) + str(cmax[0][0])
# p = D[idx]

# ans = rmax[0][1] + cmax[0][1] - p

rtmp = row.most_common(1)[0][1]
ctmp = col.most_common(1)[0][1]
rmax = []
cmax = []

for r in row.most_common():
    if r[1] < rtmp:
        break
    rmax.append(r)

for c in col.most_common():
    if c[1] < ctmp:
        break
    cmax.append(c)

ridx = str(rmax[0][0])
for d in cmax:
    if D[ridx + str(d[0])] == 0:
        ans = rmax[0][1] + d[1]
        break
else:
    ans = rmax[0][1] + d[1] - 1

cidx = str(cmax[0][0])
for d in rmax:
    if D[str(d[0]) + cidx] == 0:
        ans2 = cmax[0][1] + d[1]
        break
else:
    ans2 = cmax[0][1] + d[1] - 1

print(max(ans, ans2))

Submission status: Accepted

Solution code:
import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

in_n = lambda: int(readline())
in_nn = lambda: map(int, readline().split())
in_s = lambda: readline().rstrip().decode('utf-8')
in_nl = lambda: list(map(int, readline().split()))
in_nl2 = lambda H: [in_nl() for _ in range(H)]
in_map = lambda: [s == ord('.') for s in readline() if s != ord('\n')]
in_map2 = lambda H: [in_map() for _ in range(H)]
in_all = lambda: map(int, read().split())


def main():

    H, W, M = in_nn()

    hcnt = [0] * H
    wcnt = [0] * W

    hw = []

    for i in range(M):
        h, w = in_nn()
        h, w = h - 1, w - 1
        hw.append((h, w))

    for i in range(M):
        h, w = hw[i]
        hcnt[h] += 1
        wcnt[w] += 1

    max_h = max(hcnt)
    max_w = max(wcnt)

    ans = max_h + max_w - 1

    h_index = []
    w_index = []

    for i in range(H):
        if hcnt[i] == max_h:
            h_index.append(i)

    for i in range(W):
        if wcnt[i] == max_w:
            w_index.append(i)

    hw_set = set(hw)
    # print(h_index)
    # print(w_index)

    hn = len(h_index)
    wn = len(w_index)

    f = False
    for i in range(hn):
        for j in range(wn):
            if (h_index[i], w_index[j]) not in hw_set:
                f = True

        if f or wn * i > 10**6:
            ans += 1
            break

    print(ans)


if __name__ == '__main__':
    main()