🔙
🔝

【paiza問題集 解説】
paizaの森練習問題コンテスト過去問題セット12

文字列の一致

文字列の一致

    a = input()
    b = input()
    
    print('Yes' if a == b else 'No')
    
部分文字列

部分文字列

    a = input()
    b = input()
    
    print('Yes' if b in a else 'No')
    
グラフの連結

グラフの連結

  • paiza 解答コード例

  • n = int(input())
    t = [[False for j in range(3)] for i in range(3)]
    for i in range(n):
        a, b = map(int, input().split())
        t[a][b] = t[b][a] = True
    
    if t[0][2] or t[0][1] and t[1][2]:
        print("Yes")
    else:
        print("No")
    

  • 左は【グラフ】、右は【隣接行列】

  • 0   0 1 1
    |\  1 0 1
    1─2 1 1 0

    0   0 1 1
    |\  1 0 0
    1 2 1 0 0

    0   0 0 1
     \  0 0 1
    1─2 1 1 0

    0   0 1 0
    |   1 0 1
    1─2 0 1 0

    Yes になるのはこの4通りですが、まず最初の3つは「0」と「2」が直接繋がっているルート。もう1つは「0」から「1」を経由して「2」に到達するルートです。この2通りのパターンを最後の、

    if t[0][2] or t[0][1] and t[1][2]:
        print("Yes")
    else:
        print("No")
    

    ここで判定しています。t[0][2] というのが「0」→「2」に直接行けるかどうか、t[0][1] and t[1][2] が「0」→「1」、「1」→「2」の経路を表しています。

    隣接行列はそのまま二次元リストになりますが、この添字の要素が 1 の時、つまり辺で繋がっている時は、頂点0から頂点2に辿れるということになります。解答コード例では 1 と 0 を TrueFalse で表しています。そして隣接行列は、

    n = int(input())
    t = [[False for j in range(3)] for i in range(3)]
    for i in range(n):
        a, b = map(int, input().split())
        t[a][b] = t[b][a] = True
    

    この部分で作っています。なるほどね。

    グラフほとんど忘れちゃったよ。(;´Д`) ヤヴァイ
    ギリギリ理解できていない状態で学習を進めていたから、最後どっぷり疲れ切った記憶しか残ってない。😓

    苦手意識はあるけど、でも嫌いじゃないグラフ。💕
    グラフは苦手だけど、なぜか深さ優先探索(DFS)はできる謎。

拡張子

拡張子

  • 例1

  • s = input()
    
    i = 0
    while s[i:i+4] != '.jpg' and s[i:i+4] != '.png':
        i += 1
    
    print(i)
    
  • 例2

  • import re
    s = input()
    
    pattern = r"\.jpg|\.png"
    re_matched = re.search(pattern, s)
    
    print(re_matched.start())
    

    必ずどちらかが含まれているという保証がありますので、 文でシンプルに書けます。(効率無視😅)

    例2は正規表現を使っています。正規表現がわかるならこちらのほうが簡単です。😊

日程調整

日程調整

    l_1, r_1, l_2, r_2 = map(int, input().split())
    days = [0] * 1000
    
    for i in range(l_1, r_1+1):
        days[i] += 1
    
    for i in range(l_2, r_2+1):
        days[i] += 1
    
    print(days.count(2))
    

    それぞれの休日の期間をすべて +1 とカウントし、二人の休日が重なった所が 2 となっています。

    あとは 2 の個数をカウントしたものが答えとなります。

  • paiza 解答コード例

  • l1, r1, l2, r2 = map(int, input().split())
    
    print(max(0, min(r1, r2) - max(l1, l2) + 1))
    

    ちゃんと解説を載せてくれないと私が解説するハメに…。😁




    1
        1 5 2 8
    
    12345678
    パイザ君   
    霧島さん 

    4

    min(r1, r2) - max(l1, l2)

    min(5, 8) - max(1, 2)

    5 - 2 = 3

    実際と計算結果の間に 1 差ができるので、帳尻合わせの為に +1 しています。

    min(r1, r2) - max(l1, l2) + 1

    min(5, 8) - max(1, 2) + 1

    5 - 2 + 1 = 4

    12345678
    パイザ君l1r1   
    霧島さん l2r2

    もう言葉での説明は必要ありませんね。😙

    2
        8 10 1 5
    
    12345678910
    パイザ君       
    霧島さん     

    0

    min(r1, r2) - max(l1, l2) + 1

    min(10, 5) - max(8, 1) + 1

    5 - 8 + 1 = -2

    -2 日間はありえませんので、 max() 関数を使って下限を 0 に設定します。

    max(0, -2) = 0


    パイザ君、7連勤か。😿

    3
        4 8 2 4
    
    12345678
    パイザ君   
    霧島さん     

    1

    min(r1, r2) - max(l1, l2) + 1

    min(8, 4) - max(4, 2) + 1

    4 - 4 + 1 = 1

    12345678
    パイザ君   l1r1
    霧島さん l2r2    

    こんな仕組みです。😎

プレゼントの好み

プレゼントの好み

    n, k = map(int, input().split())
    x = list(map(int, input().split()))
    y = list(map(int, input().split()))
    
    max_idx = x.index(max(x)) + 1
    print('Yes' if max_idx in y else 'No')
    

    まず受け取ったプレゼントの価格が最も高いプレゼントの位置を見つけます。1番目から数えますので +1 します。

    あとはその位置が リスト y に含まれているかどうかを調べて結果を画面に出力して完了です。


    paiza 解答コード例はこれを、関数や in を使わずに書いているだけで、やっていることは同じです。x に 1 を足して合わせているか、y から 1 を引いて合わせているかの違いだけです。

    実際にいるよね、こういうヤツ。😓