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
未満であれば0
、0
以上の場合は \(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\) を受け取り、その領域area
を1
とします。
# 各シートが覆っている領域を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))