Official
B - Unique Nicknames Editorial by Nyaan
まずは「人 \(i\) にあだ名をつけることが可能か?」を判定する方法を考えてみましょう。
人 \(i\) につけられるあだ名 \(a_i\) の条件は次の \(2\) つです。
- \(a_i = s_i\) または \(a_i = t_i\) が成り立つ。
- \(1 \leq j \leq N, i \neq j\) を満たすすべての整数 \(j\) について \(a_i \neq s_j\) かつ \(a_i \neq t_j\) が成り立つ。
\(1\) つ目の条件から、\(a_i\) としてあり得るのは \(s_i\) または \(t_i\) のいずれかに限られます。よって、\(s_i\) または \(t_i\) の少なくとも一方が \(2\) つ目の条件を満たせば、人 \(i\) にあだ名をつけられることになります。
文字列 \(S\) が人 \(i\) のあだ名として条件を満たすかどうかは、 \(j\) を for-loop で走査して \(s_j,t_j\) と一致するものが存在するかを調べれば \(\mathrm{O}(N |s_i|)\) で判定できます。 (\(|S|\) は文字列 \(S\) の長さの意味。)
以上のアルゴリズムを実装すれば、「人 \(i\) にあだ名をつけることが可能かどうか?」を判定できます。これを人 \(1\)、人 \(2\), \(\dots\), 人 \(N\) すべての人に対して行えば、すべての人にあだ名をつけられるかを判定することができます。
計算量は \(\mathrm{O} \left(N^2 (\max(|s_i|)+\max(|t_i|)) \right)\) です。Python による実装例は次の通りです。
N = int(input())
s, t = [], []
for i in range(N):
u, v = input().split()
s.append(u)
t.append(v)
for i in range(N):
can_give_a_nickname = False
for S in [s[i], t[i]]:
s_ok = True
for j in range(N):
if i != j:
if S == s[j] or S == t[j]:
s_ok = False
if s_ok == True:
can_give_a_nickname = True
if can_give_a_nickname == False:
print("No")
exit()
print("Yes")
posted:
last update: