ABC207D - Congruence Points

考え方

  1. $S,T$の原点を重心に取り直す(座標全体を$N$倍すれば,座標変換後も整数座標になる)
  2. $S$の中で原点から最も離れている点$(x_{0}, y_{0})$を1つとる.
  3. $T$の中で,原点からの距離が$\sqrt{x_{0}^{2} + y_{0}^{2}}$に一致するものの偏角($x$軸となす角度)を求める(この集合を$\Theta$とする)
  4. 点$(x_{0}, y_{0})$が$x$軸に一致するように$S$を回転させる
  5. $S$を$\theta\in\Theta$だけ回転させて,$T$と一致するか調べる(数値誤差があることに注意!


import math

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

def rot(S, theta):
  cos = math.cos(theta)
  sin = math.sin(theta)
  return [(x * cos - y * sin, x * sin + y * cos) for x, y in S]

def adjust(S):
  x0 = sum(S[i][0] for i in range(N))
  y0 = sum(S[i][1] for i in range(N))
  return [(N * x - x0, N * y - y0) for x, y in S]

T = adjust(T)
S = sorted(adjust(S), key = lambda x: x[0] ** 2 + x[1] ** 2)

x0, y0 = S[-1]
R2 = x0 ** 2 + y0 ** 2
S = rot(S, - math.atan2(y0, x0))
theta = [0] + [math.atan2(y, x) for x, y in T if x ** 2 + y ** 2 == R2]

for a in theta:
  S2 = rot(S, a)
  cnt = 0
  for s in S2:
    for t in T:
      if (s[0] - t[0]) ** 2 + (s[1] - t[1]) ** 2 < 1e-10:
        cnt += 1
        break
  if cnt == N:
    exit(print('Yes'))

print('No')