LoginSignup
0
0

More than 3 years have passed since last update.

yukicoder contest 280 (門松コンテスト) 参戦記

Last updated at Posted at 2021-01-30

yukicoder contest 280 (門松コンテスト) 参戦記

A 1366 交換門松列・梅

書くだけではあるけど、途中でやけっぱちになってしまってこうなった.

def is_kadomatsu(a, b, c):
    if a == b or b == c or a == c:
        return False
    return min([a, b, c]) == b or max([a, b, c]) == b


a1, a2, a3 = map(int, input().split())
b1, b2, b3 = map(int, input().split())

if is_kadomatsu(b1, a2, a3) and is_kadomatsu(a1, b2, b3):
    print('Yes')
elif is_kadomatsu(b2, a2, a3) and is_kadomatsu(b1, a1, b3):
    print('Yes')
elif is_kadomatsu(b3, a2, a3) and is_kadomatsu(b1, b2, a1):
    print('Yes')
elif is_kadomatsu(a1, b1, a3) and is_kadomatsu(a2, b2, b3):
    print('Yes')
elif is_kadomatsu(a1, b2, a3) and is_kadomatsu(b1, a2, b3):
    print('Yes')
elif is_kadomatsu(a1, b3, a3) and is_kadomatsu(b1, b2, a2):
    print('Yes')
elif is_kadomatsu(a1, a2, b1) and is_kadomatsu(a3, b2, b3):
    print('Yes')
elif is_kadomatsu(a1, a2, b2) and is_kadomatsu(b1, a3, b3):
    print('Yes')
elif is_kadomatsu(a1, a3, b3) and is_kadomatsu(b1, b2, a3):
    print('Yes')
else:
    print('No')

交換の組み合わせを全パターン、素直にループでやるべきですよね. 交換して、成立するかチェックして、同じ交換をもう一度して元に戻すの繰り返し.

def is_kadomatsu(a):
    if a[0] == a[1] or a[1] == a[2] or a[0] == a[2]:
        return False
    return min(a) == a[1] or max(a) == a[1]

a = list(map(int, input().split()))
b = list(map(int, input().split()))

for i in range(3):
    for j in range(3):
        a[i], b[j] = b[j], a[i]
        if is_kadomatsu(a) and is_kadomatsu(b):
            print('Yes')
            exit()
        a[i], b[j] = b[j], a[i]
print('No')

B 1367 文字列門松

与えられた文字が同じ順番で kadomatsu に入っているか確認するだけなので、文字列検索関数を繰り返し適用すれば解けます.

S = input()

i = 0
for c in S:
    j = 'kadomatsu'.find(c, i)
    if j == -1:
        print('No')
        break
    i = j + 1
else:
    print('Yes')

C 1368 サイクルの中に眠る門松列

循環しなければ簡単に DP で解けるのだが……. 先頭の当たりを使ったか使ってないか覚えながら DP するのは大変なので、先頭の使用を禁止したパターンと、先頭から2番目までの使用を禁止したパターンを含め3回 DP して答えを求めた.

def is_kadomatsu(a, b, c):
    if a == b or b == c or a == c:
        return False
    return min([a, b, c]) == b or max([a, b, c]) == b


def solve():
    dp = [0] * (N + 1)
    for i in range(N + 1):
        if i != 0:
            dp[i] = max(dp[i], dp[i - 1])
        if i <= N - 3:
            if is_kadomatsu(A[i], A[i + 1], A[i + 2]):
                dp[i + 3] = dp[i] + A[i]
    result = dp[N]
    if is_kadomatsu(A[N - 1], A[0], A[1]):
        dp = [0] * (N + 1)
        dp[2] = A[N - 1]
        for i in range(2, N + 1):
            dp[i] = max(dp[i], dp[i - 1])
            if i <= N - 4:
                if is_kadomatsu(A[i], A[i + 1], A[i + 2]):
                    dp[i + 3] = dp[i] + A[i]
        result = max(result, dp[N])
    if is_kadomatsu(A[N - 2], A[N - 1], A[0]):
        dp = [0] * (N + 1)
        dp[1] = A[N - 2]
        for i in range(1, N + 1):
            dp[i] = max(dp[i], dp[i - 1])
            if i <= N - 5:
                if is_kadomatsu(A[i], A[i + 1], A[i + 2]):
                    dp[i + 3] = dp[i] + A[i]
        result = max(result, dp[N])
    return result


T = int(input())
for _ in range(T):
    N = int(input())
    A = list(map(int, input().split()))
    print(solve())

よくよく考えると循環しない数列を3つ用意したほうが楽ですね.

def is_kadomatsu(a):
    if a[0] == a[1] or a[1] == a[2] or a[0] == a[2]:
        return False
    return min(a) == a[1] or max(a) == a[1]


def f(a):
    dp = [0] * (N + 1)
    for i in range(N + 1):
        if i != 0:
            dp[i] = max(dp[i], dp[i - 1])
        if i <= N - 3:
            if is_kadomatsu(a[i:i + 3]):
                dp[i + 3] = dp[i] + a[i]
    return dp[N]


T = int(input())
for _ in range(T):
    N = int(input())
    A = list(map(int, input().split()))
    print(max([f(A), f(A[1:N] + A[:1]), f(A[2:N] + A[:2])]))
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0