見出し画像

[ABC311 A~D Python]トヨタ自動車プログラミングコンテスト2023#4(AtCoder Beginner Contest 311)

A問題


N = int(input())
S = input()

for i in range(N+1):
    s = S[:i]
    if s.count("A") >= 1 and s.count("B") >= 1 and s.count("C"):
        print(i)
        break

Sの左からi文字目まではS[:i]で表されます。
その中のA,B,Cの数を数えて、全て1回以上出現しているかどうか確認しましょう。

B問題

N, D = map(int, input().split())
day = [[] for _ in range(D)]

for i in range(N):
    S = input()
    for j in range(D):
        day[j].append(S[j])


all_free = ["o" for _ in range(N)]

ans = 0
c = 0
for i in range(D):
    if day[i] == all_free:
        c += 1
    else:
        ans = max(ans, c)
        c = 0
ans = max(ans, c)
print(ans)

現状のSは人の番号Nごとにまとめてありますが、
求めるべきは1日のうちに何人暇か?なので、
日Dごとに配列を変化させると解きやすいと思います。

何日連続するかをcでカウントアップさせ、
最終的には最大のcを出力することになります。

C問題

N = int(input())
A = list(map(int, input().split()))


from collections import deque, defaultdict
dd = defaultdict(list)
for i in range(N):
    dd[i].append(A[i])

for i in range(1, N+1):
    ans = []
    visited = [False for _ in range(N+1)]
    d = deque()
    d.append(i)
    while d:
        now = d.popleft()
        visited[now] = True
        ans.append(now)
        for j in dd[now]:
            if j == i:
                print(len(ans))
                print(*ans)
                exit()
            if not visited[j]:
                d.append(j)
                ans.append(j)



        

全ての頂点から順に辺をたどっていき、有向閉路になるかどうかを調べます。

移動中にたどった点はansに保存しておくことで、
出発点iと到達点jが一致したら、
出発点に戻ってきた、つまり、閉路が確認できたということなので、
これまでの道のりとその長さを出力します。

D問題

from collections import deque
N, M = map(int, input().split())
S = [list(input()) for _ in range(N)]

visited = [[False]*M for _ in range(N)]
stoped = [[False]*M for _ in range(N)]

d = deque()
d.append((1, 1))
visited[1][1] = True
dict = [(0, 1), (1, 0), (0, -1), (-1, 0)]
while d:
    x, y = d.popleft()
    # print(x,y)
    for X, Y in dict:
            now_x = x
            now_y = y
            while S[now_x+X][now_y+Y] == ".":
                now_x += X
                now_y += Y
                visited[now_x][now_y] = True
            if not stoped[now_x][now_y]:
                stoped[now_x][now_y] = True
                d.append((now_x, now_y))
ans = 0
for i in range(N):
    for j in range(M):
        if visited[i][j]:
            ans += 1
print(ans)

2023/07/25追記しました。

訪れることができる全ての地点の個数を出力する問題です。
dfs等で、実際にグリッド上を動かしながら考えていきましょう。
同じマスを何周もしないように、
一度ぶつかった岩のマスは配列stopedで保存し、
永遠にプログラムが回らないようにすることで、
答えを導き出すことができます。

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