【AtCoder】ABC318解説(Python)

THIRD プログラミングコンテスト 2023 アルゴ(AtCoder Beginner Contest 318)の解説記事です。

目次

ABC318 A – Full Moon

問題

解説1

M日目からN日目の間、P日ごとに解答に1を足す操作を行う。

解説

まず入力 \(N\) , \(M\) , \(P\) をintとして受け取ります。

# 入力
N,M,P=map(int, input().split())

解答用の変数を初期値0で用意します。

# 解答用の変数
ans=0

\(M\) 日目から \(N\) 日目の間、 \(P\) 日ごとに解答に1を足す操作を行う。
最後に答えを出力します。

# M日目からN日目の間
while M<=N:
    # 解答に1を足す
    ans+=1
    # P日後
    M+=P

# 解答を出力
print(ans)

解答

# 入力
N,M,P=map(int, input().split())

# 解答用の変数
ans=0

# M日目からN日目の間
while M<=N:
    # 解答に1を足す
    ans+=1
    # P日後
    M+=P

# 解答を出力
print(ans)

解説2

植木算として考える。

解説

問題文は \(M\) メートル先から\(N\) メートルの先までの道に \(P\) メートル間隔で木を植えるとき何本植えられますか?と同じ意味になります。

つまり、長さ \(N – M\) メートルの道に \(P\) メートル間隔で木を植えるとき何本植えられますか?と言い換えられるので、\(N – M\)が0未満であれば00以上の場合は \(N – M\) を \(P\) で割った整数部分プラス1になります。

これは次のように書けます。

print(0 if N-M<0 else (N-M)//P+1)

解答

# 入力
N,M,P=map(int, input().split())

# 解答を出力
print(0 if N-M<0 else (N-M)//P+1)

ABC318 B – Overlapping sheets

問題

解説

各シートが覆っている領域を配列で持ち、面積を計算する。

解説

まず入力 \(N\) をintとして受け取ります。
100*100の領域を初期値0の配列areaとして定義します。
出力用の変数である、1 枚以上のシートによって覆われている領域 の面積をSとします。

# 入力
N=int(input())

# 100*100の領域(初期値0)
area=[[0]*100 for _ in range(100)]

# 出力用の変数(1 枚以上のシートによって覆われている領域 の面積)
S=0

各シートが覆っている領域を求めます。
\(A, B, C, D\) を受け取り、その領域area1とします。

# 各シートが覆っている領域を1とする
for i in range(N):
  A,B,C,D=map(int,input().split())
  for x in range(A,B):
    for y in range(C,D):
      area[x][y]=1

各シートが覆っている面積の計算します。

# 各シートが覆っている面積の計算
for x in range(100):
  for y in range(100):
    S+=area[x][y]

面積をSを出力します。

# 答えを出力
print(S)

解答

# 入力
N=int(input())

# 100*100の領域(初期値0)
area=[[0]*100 for _ in range(100)]

# 出力用の変数(1 枚以上のシートによって覆われている領域 の面積)
S=0

# 各シートが覆っている領域を1とする
for i in range(N):
  A,B,C,D=map(int,input().split())
  for x in range(A,B):
    for y in range(C,D):
      area[x][y]=1

# 各シートが覆っている面積の計算
for x in range(100):
  for y in range(100):
    S+=area[x][y]

# 答えを出力
print(S)

ABC318 C – Blue Spring

問題

解説

i日目の旅行にかかる運賃の通常料金を高い順にソートし、D日ごとに1日周遊パスを使うかをシミュレートする。

解説

i日目の旅行にかかる運賃の通常料金を高い順にソートし、D日ごとに1日周遊パスを使うかをシミュレートします。そのとき、1 日周遊パスの金額より大きかった場合は1 日周遊パスを購入し、安かった場合はその金額を支払います。

解答

# 入力
N,D,P=map(int,input().split())
F=list(map(int,input().split()))

# Fを降順にソート
F.sort(reverse=True)

# 合計金額
ans=0
# 最後に1日周遊パスを利用して何日経ったか?
cnt=0
# 最後に1日周遊パスを利用して何円使用したか?
tmp=0

# Fを降順にソートした1日目から順にシミュレートする
for i in range(N):
  # 最後に1日周遊パスを利用して何日経ったか?+1日
  cnt+=1
  # 最後に1日周遊パスを利用して何円使用したか?+F[i]円
  tmp+=F[i]
  # 最後に1 日周遊パスを利用してD日経ったとき
  if cnt==D:
    # 1日周遊パスの金額より大きかった場合
    if tmp>P:
      # 1日周遊パスを使用する
      ans+=P
    else:
      # 1日周遊パスを使用しない
      ans+=tmp
    # 0に戻す
    cnt=0
    tmp=0
# それまでの合計+(1日周遊パスを使用しない場合と1日周遊パスを使用した場合の安い方)を出力
print(ans+min(tmp,P))
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次