이분 탐색으로 개고생. Defaultdict은 자체 처리 시간이 길다는 교훈 하나를 얻고 투 포인터로 시도해보았다.
A + B + C + D를 (A+B) + (C+D)로 묶어 줄 수 있으므로, 가능한 경우의 수를 따져 두 개의 리스트로 바꿔주자(O(N^2)), 이를 정렬하고, 투 포인터로 합이 되는 경우의 수를 찾아주면 된다. (O(N^2))
풀이 코드
import sys
N = int(input())
num_list = [list() for _ in range(4)]
for _ in range(N) :
for i, num in enumerate(map(int, input().split())) :
num_list[i].append(num)
new_num_list = [list() for _ in range(2)]
for i in range(N) :
for j in range(N) :
for k in range(2) :
new_num_list[k].append(num_list[2*k][i] + num_list[2*k+1][j])
for i in range(2) :
new_num_list[i].sort()
answer, i, j = 0, 0, N**2-1
while i < N**2 and j > -1 :
if new_num_list[0][i] + new_num_list[1][j] == 0 :
ti, tj = i, j
while i < N**2 and new_num_list[0][ti] == new_num_list[0][i] :
i += 1
while j > -1 and new_num_list[1][tj] == new_num_list[1][j] :
j -= 1
answer += (i - ti) * (tj - j)
elif new_num_list[0][i] + new_num_list[1][j] > 0 :
j -= 1
else :
i += 1
print(answer)