トヨタ自動車プログラミングコンテスト2023#3(AtCoder Beginner Contest 306)をPythonで解く

投稿日:  更新日:2023/09/12

Atcoder Python

B!
Daniel AgreloによるPixabay(https://pixabay.com/)からの画像

こんにちは, Shinoryoです.

今回はトヨタ自動車プログラミングコンテスト2023#3(AtCoder Beginner Contest 306)を, Pythonで解いてみた結果を書き連ねていこうと思います.

A - Echo

愚直に実装すれば問題ありません.

N = int(input())
S = list(input())
print("".join([S[i // 2] for i in range(2*N)]))

B - Base 2

i=063Ai×2iを求めればよいです.

A = list(map(int, input().split()))
print(sum(A[i] * (2**i) for i in range(len(A))))

C - Centers

実装方針は以下のようになります.

  1. Aの要素を順に調べていく.
    1. 整数iが出現した回数Biを, 配列を利用して記録する.
    2. ある整数iに対してBi=2となったら, 出力順を記録する配列Ciを追加する.
# 入力
N = int(input())
A = list(map(int, input().split()))
# Aの要素を順に調べていく
# 今までの発生回数を記録
appearance_count = [0 for _ in range(N + 1)]
# 1~Nを出力する順にappendする用の配列
ans = []
for i in range(3 * N):
appearance_count[A[i]] += 1
# 発生回数が2回になったとき、ansにその整数をappendする
if appearance_count[A[i]] == 2:
ans.append(str(A[i]))
# 出力
print(" ".join(ans))

D - Poisonous Full-Course

ここでは, 動的計画法(dynamic programming)を用いることを考えます. 以下の2次元配列を用意して, 入れるべき値を計算していきます.

  • dpi,j:料理iまでの料理を食べるか下げてもらうか選択したとき, 高橋くんが状態jである場合の, 食べた料理の美味しさの総和の最大値
  • 状態j=0:高橋くんがお腹を壊していない状態
  • 状態j=1:高橋くんがお腹を壊している状態

初期状態のため, dp0,0=0, dp0,1=0です. 次に運ばれてくる料理が解毒剤入り(Xi=0)のとき, この後高橋くんがお腹を壊さなかった場合の, 食べた料理の美味しさの総和の最大値は, 以下の3つの場合の最大値になります.

  • 高橋くんがお腹を壊していない状態で, その料理を食べなかった(dpi1,0).
  • 高橋くんがお腹を壊していない状態で, その料理を食べた(dpi1,0+Yi).
  • 高橋くんがお腹を壊している状態で, その料理を食べた(dpi1,1+Yi).

次に運ばれてくる料理が解毒剤入り(Xi=0)のとき, この後高橋くんがお腹を壊した場合の, 食べた料理の美味しさの総和の最大値は, 以下の場合の値になります.

  • 高橋くんがお腹を壊している状態で, その料理を食べなかった(dpi1,1).

次に運ばれてくる料理が毒入り(Xi=1)のとき, この後高橋くんがお腹を壊さなかった場合の, 食べた料理の美味しさの総和の最大値は, 以下の場合の値になります.

  • 高橋くんがお腹を壊していない状態で, その料理を食べなかった(dpi1,0).

次に運ばれてくる料理が毒入り(Xi=1)のとき, この後高橋くんがお腹を壊した場合の, 食べた料理の美味しさの総和の最大値は, 以下の2つの場合の最大値になります.

  • 高橋くんがお腹を壊していない状態で, その料理を食べた(dpi1,0+Yi).
  • 高橋くんがお腹を壊している状態で, その料理を食べなかった(dpi1,1).

以上のことを考慮して配列dpの値を計算していきます. 最終的に出力するべき値は, dpN,0dpN,1のいずれか大きい方です.

# 入力
N = int(input())
# 配列dpの初期状態
dp = [[0, 0] for _ in range(N + 1)]
# 配列dpを順番に計算
for i in range(1, N + 1):
X, Y = map(int, input().split())
if X == 0:
dp[i][0] = max(dp[i - 1][0], dp[i - 1][0] + Y, dp[i - 1][1] + Y)
dp[i][1] = dp[i - 1][1]
else:
dp[i][0] = dp[i - 1][0]
dp[i][1] = max(dp[i - 1][0] + Y, dp[i - 1][1])
# 出力
print(max(dp[N]))

動的計画法は, 他のページでも解説しています.

E以降

E以降は私の能力不足故に省略いたします.

参考にしたサイト等

Search

About Me

自分の写真
理系大学生でした. Bloggerを利用して発信を行っています.

Labels