ebisukeプログラミング初心者脱出黙示録

30歳を過ぎてから始めたプログラミングと競プロの記録。Pythonで取り組んでいます。Arduinoで電子工作も

AtCoder-ABC222 C - Swiss-System Tournament【Python解答例】

AtCoder Beginner Contest222のC問題についてPythonの解答例を記事にしていきます。
Exawizards Programming Contest 2021(AtCoder Beginner Contest 222) - AtCoder



AtCoder Beginner Contest222 C - Swiss-System Tournament

C - Swiss-System Tournament

問題文

1 から 2N の番号がついた 2N 人でじゃんけん大会をします。

大会は M ラウンドからなり、各ラウンドは、全ての人が 1 度ずつ参加するような 1 対 1 の N 試合からなります。

i=0,1,…,M について、i ラウンド目の終了時点での順位を次のように決めます。

・i ラウンド目までの勝数が多い方が上位
・i ラウンド目までの勝数が同じときは、番号が小さい方が上位
また、i=1,…,M について、i ラウンド目の各試合の組み合わせを次のように決めます。

・各 k=1,2,…,N について、i−1 ラウンド目終了時点の順位が 2k−1 位の人と 2k 位の人が試合をする
各試合では、対戦する 2 人がそれぞれ 1 度だけ手を出し、勝ち・負け・引き分けのいずれかの結果が発生します。

未来予知ができる高橋君は、人 i が j ラウンド目の試合で出す手が A i,j​ であることを知っています。
A i,j​ は G, C, P のいずれかであり、それぞれグー、チョキ、パーを表します。

M ラウンド目終了時点の順位を求めてください。

制約

・1≤N≤50
・1≤M≤100
・A i,j​ は G, C, P のいずれか

解答例

def judge(a,b):
    if a == "G" and b == "C":
        return True
    elif a == "C" and b == "P":
        return True
    elif a == "P" and b == "G":
        return True
    else:
        return False


n, m = map(int,input().split())

A = []
for i in range(2*n):
    A.append(input())

rank = []
for i in range(2*n):
    rank.append([200,i])

for j in range(m):
    for i in range(n):
        num1 = rank[2*i][1]
        num2 = rank[2*i+1][1]
        if judge(A[num1][j],A[num2][j]):
            rank[2*i][0] -= 1
        elif judge(A[num2][j],A[num1][j]):
            rank[2*i+1][0] -= 1
    rank.sort()

for i in range(2*n):
    print(rank[i][1]+1)

解説

順位が2k-1位と2k位の人がMラウンドじゃんけんをおこない、Mラウンド終了後の順位を答える問題です。

じゃんけんの勝敗を判定するため、aとbという手のときaが勝てばTrue、引き分けか負けならFalseを返すjudge関数を作成しました。

順位の管理は初期スコアを200としたrank配列で行います。
ラウンドごとにスコアでソートするため、勝てばスコアを減らしていく方式にしました。
(わかりにくいですがスコアが低いほど順位が高い方式です (^_^;))

あとはラウンドごとに2k-1と2k位の人の手を確認し、どちらかが勝つならば勝った方のスコアを1減らしていきました。
ラウンドが終わるとrank配列をソートし、順位を更新します。

このシミュレーションをMラウンド繰り返し、最後に順位を出力していけばOKでした。


ABC222の関連記事はこちら
ebisuke33.hatenablog.com
ebisuke33.hatenablog.com