Paizaのスキルチェック過去問「みんなでしりとり」を解いた話
がんばりました。
こちらは公開OKのやつです。
書いたコード
# coding: utf-8
N,K,M = [int(i) for i in input().split()]
d_dict = {input() for i in range(K)}
m_list = [input() for i in range(M)]
n_list = [i+1 for i in range(N)]
n = 0
flg = 0
for i in range(len(m_list)):
z = ""
if m_list[i] in d_dict:
d_dict.remove(m_list[i])
if m_list[i][-1:] == "z":
z = n_list[n]
flg = 0
elif flg == 1 and m_list[i-1][-1:] != m_list[i][:1]:
z = n_list[n]
flg = 0
elif flg == 0:
flg = 1
else:
z = n_list[n]
flg = 0
if flg == 1 or n == len(n_list)-1:
if n >= len(n_list)-1:
n = 0
else:
n += 1
if z != "":
n_list.remove(z)
print(len(n_list))
for i in n_list:
print(i)
解説的ななにか
コード汚くてすまない…
最初の定義部分
最初の3行はInputされるやつをそれぞれ格納しているだけです。
d_dict
で使ってもいい単語リストを格納(dictって書いてるけどこれ辞書型じゃなくね?)
m_list
で発言されたものをリスト化
n_list
で参加者の管理
n = 0
は発言者の順番を管理するやつ
flg = 0
は最初の人かどうかを管理するフラグ(0=最初の人、1=2番目以降の人)
For文部分
for文はm_list
を主軸にしました。
このとき、for i in m_list:
としないのがポイント。
コレをやると、条件である
最初の人以外の発言の頭文字は、直前の人の発言の最後の文字と一緒でなければならない。
の比較ができなかった。
発言と単語リストの比較
if m_list[i] in d_dict:
で、発言した単語が単語リストにあるかどうかを調べます。
ヒットすれば、単語リストから該当単語をd_dict.remove(m_list[i])
で削除します。
こうすることで、二重発言のチェックとそもそもリストにない単語を同時に見ることができます。
ヒットしなければ、無条件で発言者を脱落させ、flg
を0
(最初の発言者)にします。
脱落者の処理については後述します。
末尾にzが含まれていないか確認
d_dict
に含まれていてもzで終わる単語はNG扱いとなっているので、含まれていれば脱落させます。
末尾だけみればいいので、m_list[i][-1:] == "z"
の[-1:]
部分で末尾だけスライスします。
コレは後述の末尾と先頭を比較する際にも使うテクです。
一個前の末尾と今の先頭の文字を比較する
まず、m_list[i-1][-1:] != m_list[i][:1]
部分の解説をします。
この部分は前の単語と今の単語の末尾と先頭を比較するものです。
前述したfor i in m_list:
としない理由がこれです。
単語を直接ぶちこむと比較できなくなってしまうため、for i in range(len(m_list))
としたのです
スライスについてはもっと良い解説をしている方がいるはずですので、そちらで。
このまま使用すると、間違えた次の人にも適用されてしまうため先頭じゃないフラグflg=1
の人のみを対象とするため、flg==1
を追加して以下とします。
flg == 1 and m_list[i-1][-1:] != m_list[i][:1]
次の人へ
一折見終わったら次の人へパスします。
パスするには単純にn += 1
をすれば回せます。
が、ここで2つ問題が発生します。
1つ目が、最後まで回ったときどうするのか。
2つ目が、脱落者の部分をどうするのか。
それを一気に解決するのが次の部分です。
if flg == 1 or n == len(n_list)-1:
if n >= len(n_list)-1:
n = 0
else:
n += 1
1つ目については
n
がlen(n_list)-1
と同じになったら0
にすることで解決します。
これ2個めのifいらないのでは…?
2つ目の部分については、
脱落させると順番がズレます。
次の人が今のn
の位置に収まるので実は何もする必要がないです。
それ以外の場合n += 1
します。
脱落者の処理
脱落処理でz
に脱落者番号を格納しておき、その都度処理します。
if z != "":
n_list.remove(z)
出力
最後に出力して終わりです。
print(len(n_list))
for i in n_list:
print(i)
最後に
重複の管理と参加者の管理がミソなのかなと思います。
もっとこうしたらいいよっていうのがあったら教えて下さい
Author And Source
この問題について(Paizaのスキルチェック過去問「みんなでしりとり」を解いた話), 我々は、より多くの情報をここで見つけました https://qiita.com/silvertirol/items/8f7c8bf5d82c1f2c653d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .