🐡
# ABC188 C - ABC Tournament
ABC188 C - ABC Tournament
問題へのリンク
問題概要
準優勝する、すなわち最後に行われる対戦において負ける選手の番号を求めよ。
制約
ABC中の解答
トーナメントの準優勝者を見つける問題。 TLE
にはならないと判断して、以下の関数
出力は選手の番号であり同じ値のレートの選手はいないので最後にindexを調べるために配列をなめて選手の番号を求めた。
import sys
import numpy as np
input = sys.stdin.buffer.readline
N = int(input())
A = np.array(list(map(int, input().split())))
_A = A
def f(arr):
new_arr = np.zeros((len(arr) // 2), dtype='int')
for i in range(0, len(arr), 2):
new_arr[i // 2] = max(arr[i], arr[i + 1])
return new_arr
for _ in range(N - 1):
A = f(A)
second = min(A)
for i, a in enumerate(_A, start=1):
if second == a:
print(i)
解法2
evimaさんが内包表記を使えばより簡単にかけることを示していたのでメモ
後からindexを調べるために配列をなめる必要もないように max
はデフォルトでは1つ目の要素が等しい時のみ2つ目以降の要素で比較するようだ。
N = int(input())
A = list(map(int, input().split()))
p = [(A[i], i + 1) for i in range(len(A))]
while len(p) > 2:
p = [max(p[i * 2], p[i * 2 + 1]) for i in range(len(p) // 2)]
print(min(p)[1])
公式解法2
準優勝は 優勝者と反対の山で一番レートが大きい人
だそうだ。確かに!と思った。
したがって参加者を半分に分けてそれぞれの山の最大値をとり、その2つの値のうち小さい方が準優勝、大きいほうが優勝者となる。
N = int(input())
A = list(map(int, input().split()))
v = min(max(A[:2**N // 2]), max(A[2**N // 2:]))
for i, a in enumerate(A, start=1):
if a == v:
print(i)
evimaさんのようにindexを参照するなら以下のようになる。
N = int(input())
A = [(a, i) for i, a in enumerate(map(int, input().split()), start=1)]
v = min(max(A[:2**N // 2]), max(A[2**N // 2:]))
print(v[1])
Discussion