
각 우주에서 행성들의 크기가 주어졌을 때, 균등한 우주의 쌍 개수를 구하는 문제이다.
아래 조건이 두 우주가 균등한 조건이다.
각 우주들을 모두 비교하면 N이 최대 10,000이기 때문에 시간초과가 될 것이다.
따라서 각 행성 간의 대소비교를 편하게 하기 위해 좌표 압축이라는 테크닉을 사용한다.
그런데 3.에서 정렬된 값들을 봤을 때 앞서 비교한 값과 같다면 인덱스를 그전 것과 똑같이 해야한다.
예를 들어 A : [40, 10, 10], B : [30, 10, 20] 일 때,
A : 40 > 10 = 10 이고 B : 30 > 10 < 20 이여서 두 우주는 균등하지 않지만,
A에서 좌표압축할 때 1.[[40, 0], [10, 1], [10, 2]] -> 2.[[10, 1], [10, 2], [40, 0]] -> 3.[[0, 1], [1, 2], [2, 0]] -> 4.[[2, 0], [0, 1], [1, 2]]가 되면 B와 같아진다.
따라서 3.에서 앞에서 비교한 값과 같다면 인덱스를 올리지 말고 같게 해야한다. 3.[[0, 1], [0, 2], [2, 0]]
이렇게 나온 압축좌표를 join함수로 합치고 그것을 키로 딕셔너리에 개수를 저장한다.
개수에 따라 nC2를 적용하면 균등한 우주 쌍을 구할 수 있다.
nCr은 math.comb()를 이용하면 쉽게 구할 수 있다.
해결언어 : Python
import sys
input = sys.stdin.readline
import math
m, n = map(int, input().split())
def compress(lst):
tmp = []
for i, size in enumerate(lst):
tmp.append([size, i])
tmp.sort()
pre = -1
for idx, [size, _] in enumerate(tmp):
if pre == size:
tmp[idx][0] = tmp[idx-1][0]
else:
tmp[idx][0] = idx
pre = size
tmp.sort(key=lambda x:x[1])
result = []
for i, _ in tmp:
result.append(i)
return result
spaces = {}
for _ in range(m):
lst = compress(list(map(int, input().split())))
key = ''.join(map(str, lst))
if key in spaces:
spaces[key] += 1
else:
spaces[key] = 1
cnt = 0
for val in spaces.values():
cnt += math.comb(val, 2)
print(cnt)

끝으로..
좌표 압축에 대해 배울 수 있었다.