LoginSignup
3
1

ABC322をPythonで(A~E)

Last updated at Posted at 2023-09-30

AtCoder Beginner Contest 322
https://atcoder.jp/contests/abc322

A問題

全探索をする

A
n = int(input())
s = input()

for i in range(n - 2):
    if s[i:i+3] == "ABC":
        print(i + 1)
        exit()

print(-1)

B問題

接頭辞が違ったら答えに+2
接尾辞が違ったら答えに+1

B
n, m = map(int, input().split())
s = input()
t = input()

f1 = s == t[:n]
f2 = s == t[-n:]

ans = 0
if not f1:ans += 2
if not f2:ans += 1
print(ans)

C問題

最終日から数えていくとよい
花火を打ち上げる日をsetで管理するとやりやすい

C
n, m = map(int, input().split())
a = set(map(lambda x:int(x) - 1, input().split()))

day = [0] * n
for i in range(n - 1, -1, -1):
    if i not in a:
        day[i] += day[i + 1] + 1

for d_i in day:
    print(d_i)

D問題

各ポリオミノを座標で管理する
そのうえで次のことを行う
1、a, b, cを平行移動させて4x4に収まるか全探索
2、aは回転させずにbやcを90度回転させる

D
def make():
    res = []
    for i in range(4):
        for j, s_i in enumerate(input()):
            if s_i == "#":
                res.append((i, j))
    return res

a = make()
b = make()
c = make()

def turn(x):
    res = []
    for i, j in x:
        res.append((j, 4 - i))
    return res

# 平行移動
def solve(a, b, c):
    for a_i, a_j in [(i, j) for i in range(-4, 4) for j in range(-4, 4)]:
        for b_i, b_j in [(i, j) for i in range(-4, 4) for j in range(-4, 4)]:
            for c_i, c_j in [(i, j) for i in range(-4, 4) for j in range(-4, 4)]:
                field = [[0] * 4 for _ in range(4)]
                flag = True
                for i, j in a:
                    if 0 <= i + a_i < 4 and 0 <= j + a_j < 4 and field[i + a_i][j + a_j] == 0:
                        field[i + a_i][j + a_j] += 1
                    else:
                        flag = False
                for i, j in b:
                    if flag and 0 <= i + b_i < 4 and 0 <= j + b_j < 4 and field[i + b_i][j + b_j] == 0:
                        field[i + b_i][j + b_j] += 1
                    else:
                        flag = False
                for i, j in c:
                    if flag and 0 <= i + c_i < 4 and 0 <= j + c_j < 4 and field[i + c_i][j + c_j] == 0:
                        field[i + c_i][j + c_j] += 1
                    else:
                        flag = False
                if flag:
                    print("Yes")
                    exit()
    return False

# ミノが16個ちょうどでないときは不適
if len(a) + len(b) + len(c) != 16:
    print("No")
    exit()

# b,cを回転させるパターンを全探索
for _ in range(4):
    for _ in range(4):
        solve(a, b, c)
        c = turn(c)
    b = turn(b)

print("No")

E問題

dp問題
k=1のときはナップザック問題とおなじ
ただしkが変わるためそのままでは出来ない
つねにk=5としてやってもできなくはないだろうが、自分は違う方法を取った

i番目(0-index)のパラメーターに(p+1)**iを掛けて、それらの総和をとる
するとこの和と各パラメーターが一対一対応を取る

これを利用することでdpが解ける

E
n, k, p = map(int, input().split())

Pattern = (p + 1) ** k
# dp[i] = iの時の最小コスト
# i = x_0 + x_1*(p+1) + x_2*(p+1)**2 + ...

dp = [INF] * Pattern
dp[0] = 0
for _ in range(n):
    c, *a = map(int, input().split())
    for now in range(Pattern - 1, -1, -1):
        lst = []
        i = now
        for _ in range(k):
            lst.append(i % (p + 1))
            i //= (p + 1)
        for j, a_i in enumerate(a):
            lst[j] += a_i
        to = 0
        for j, l_i in enumerate(lst):
            to += min(l_i, p) * (p + 1) ** j
        dp[to] = min(dp[to], dp[now] + c)

print(dp[-1] if dp[-1] < INF else -1)
3
1
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
3
1