見出し画像

[ABC263]LINE Verda プログラミングコンテスト(AtCoder Beginner Contest 263) A~C問題Python解説

A問題

A, B, C, D, E = list(map(int, input().split()))
card = [A, B, C, D, E]
a = card.count(A)
b = card.count(B)
c = card.count(C)
d = card.count(D)
e = card.count(E)
# print(set([a,b,c,d,e]))
if set([a,b,c,d,e]) == {2, 3}:
    print("Yes")
else:
    print("No")

フルハウスを知らなくても、もちろん解くことができます。
フルハウスとは問題文のとおり
あるカードXが3枚、カードYが2枚の合わせて5枚の組が存在するとき、フルハウスであるといえます。
なので、A~Eの5枚が上記のフルハウスの条件を満たすか判断すればいいという訳です。

やり方は多数考えられますので、参考程度に読んでください。
まず、リストcardにA~Eのカードをすべて入れます。
次にA~Eのカードそれぞれについて、同じカードが何枚あるか数えます。
使う関数は、count関数です。
list.count(要素)でlistに要素が何個あるか数え上げます。

ここで、フルハウスを満たすには、
カードの種類は問いませんが、
A~Eの枚数を数えたa~eが2,2,3,3,3であればいいですね。
後はa~eをリストに直してsetで種類を数えて、2,3のみを含めば
フルハウスの条件を満たします。

もちろんa~eが2,3,3,3,3にはなりませんね。
なのでこの条件分岐で、正答を出すことができます。

B問題

n = int(input())
p = [0] + list(map(int, input().split()))
c = 1
for i in range(n):
    if p[n - 1] == 1:
        print(c)
        exit()
    else:
        c += 1
        n = p[n-1]

制約からN<50と少ないので、素直にたどっていくのがいいと思います。

イメージは人Nの1代目前、2代前、…と探していき、
人1に行きついたら何代前だったのかを出力します。

まず、初期値として、何代前かを数えるcを与えます。
0代前ということは考えられないので、c=1です。

もし、人Nが人1と同じだとしたら
何代前かを表すcを出力して終了です。
人Nが人1ではないときは
cに+1をして人Nを更新します。

このような2変数を更新するプログラムはよく頻出なので、覚えておきましょう。

C問題

import itertools

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

l = [i for i in range(1, m+1)]
ans = []
for i in itertools.combinations(l, n):
    i = list(i)
    ans.append(i)
# print(ans)
ans.sort()
for i in range(len(ans)):
    print(*ans[i])

問題文が難しく書いてありますが、
入力例を見たほうが納得しやすいかもしれません。

要は、1~Mの整数で、N個の全順列の中で、
単調増加のものを出力するという問題です。
例えば、N=2,M=2の時、
2個の全順列は
1,2
2,1
の2つあるのですが、
単調増加なのは1,2だけなので、
1,2
だけを出力します。

では、順列を全て考えて、
1つ1つ単調増加なのか確認するのは大変なので、
組み合わせを出力して小さい順にsortする方法でやってみましょう。
順列では(1,2)と(2,1)が当てはまりますが、
組み合わせでは(1,2)のみが該当します。
つまり、組み合わせで考えて、
その都度小さい順にsortすれば全部出力できます。

まず、組み合わせはitertools.combinations()で作ることができます。
候補となる整数1~Mをリストlに格納して、
その中からN個の組み合わせを取ってきます。
取ってきた組み合わせの中身を小さい順にsortして、
リストansに追加します。

最後に辞書順に出力しなければいけないので、ansもsortして、
整数列にするために*listとして出力します。

この記事が気に入ったらサポートをしてみませんか?