パナソニックプログラミングコンテスト(AtCoder Beginner Contest 195)をPythonで解く

投稿日:  更新日:2022/09/02

Atcoder Python

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

こんにちは, Shinoryoです.

今回はパナソニックプログラミングコンテスト(AtCoder Beginner Contest 195)を, Pythonで解いてみた結果を書き連ねていこうと思います.

A - Health M Death

条件を書いてif文で分岐させれば問題ないです.

# 入力
M, H = [int(x) for x in input().split()]
# 出力
if H % M == 0:
print("Yes")
else:
print("No")

B - Many Oranges

最も少ない個数lowerは, BグラムのみかんでWキログラム以上となるようにし, オーバーした分はより軽いみかんに置き換えることで得られます. 具体的には, 1000W/Bの小数点以下を切り上げることによって得られます.

最も多い個数upperは, AグラムのみかんでWキログラム以下となるようにし, 足りない分はより重いみかんに置き換えることで得られます. 具体的には, 1000W/Aの小数点以下を切り捨てることによって得られます.

切り上げ, 切り捨ての計算は, mathモジュールのceil()(切り上げ), floor()(切り捨て)を用いると楽です. 整数int型が返されます.

なお, lower>upperの場合は, オーバーした分はより軽いみかんに置き換えてもWキログラムにならない場合に相当します.

import math
# 入力
A, B, W = [int(x) for x in input().split()]
# lower(最も少ない個数)は、BグラムのみかんでWキログラム以上となるようにし、
# オーバーした分はより軽いみかんに置き換えることで得られる
lower = math.ceil(1000 * W / B)
# upper(最も多い個数)は、AグラムのみかんでWキログラム以下となるようにし、
# 足りない分はより重いみかんに置き換えることで得られる
upper = math.floor(1000 * W / A)
# もしupper < lowerなら、置き換えることができない
# それを踏まえて出力する
if upper < lower:
print("UNSATISFIABLE")
else:
print(lower,upper)

C - Comma

一般に, 103iから103(i+1)1までのコンマの数は,

(1)ansi=(103(i+1)103i)×i

で得られます*1. Nの桁数Dに関して, D13で割った商をAとすると, 1からAまでのiに関してansiを合計することによって, 1から103A1までのコンマの数を得ることができます. 103Aからのコンマの数は, 別に求める必要があります.

A=0,1の場合も, range()の性質から, 同様のコードで求めることができます.

# 入力(文字列型)
N_str = input()
# 10の何乗オーダーかを3で割った商
N_len_3 = (len(N_str) - 1) // 3
# 答えを格納する変数
ans = 0
# 10^(3*N_len_3) - 1以下のコンマの数を調査
for i in range(1, N_len_3):
ans += (10**(3*(i+1)) - 10**(3*i)) * i
# 10^(3*N_len_3)以上のコンマの数を調査
if N_len_3 > 0:
ans += (int(N_str) - 10**(3*N_len_3) + 1) * N_len_3
# 出力
print(ans)

D - Shipping Center

価値の大きい荷物から順に, できる限り容量の小さい箱に詰めていくことで, 荷物の価値の合計が最大になります.

価値の大きい荷物から順に調べていく際に, WVの値を格納した2次元配列を, Vの大きい順にソートする必要が出てくるかと思います. 多次元リストのソートでは, 1番目の値から順に比較されますので, Vの値を先頭にしておいた方が楽でしょう*2.

下のコードでは, すでに荷物を入れた箱を, 使える箱のリストから除外するにあたって, del文を使用しています. もちろん, インデックスでスライスして上書きしても構わないと思います.

# 入力
N, M, Q = [int(x) for x in input().split()]
VWmatrix = []
for _ in range(N):
Wi, Vi = [int(x) for x in input().split()]
VWmatrix.append([Vi, Wi])
X = [int(x) for x in input().split()]
# VWmatrixをVの大きい順にソート
VWmatrix.sort(reverse = True)
# 各クエリに対してループ
for query in range(Q):
# 答えを格納する変数
ans = 0
# L, Rを入力
L, R = [int(x) for x in input().split()]
# Xから使えないものを除外
newX = X[:(L-1)] + X[R:]
# 全ての荷物iに対してループ(Vの高い順に)
for i in range(N):
# 荷物iが入る最小の箱を探す
# 使用する変数を用意
minbox_size = 10**6 + 1
minbox_number = None
# newXの要素に対してループ(indexも欲しいのでこのように)
for j in range(len(newX)):
# 荷物iが入る かつ 今までのものより小さいならば、上の変数に格納
if newX[j] >= VWmatrix[i][1] and minbox_size > newX[j]:
minbox_size = newX[j]
minbox_number = j
# 荷物が入ったら……
if minbox_number != None:
# ansに荷物iの価値を加える
ans += VWmatrix[i][0]
# newXからminbox_numberを除外
del newX[minbox_number]
# 答えを出力
print(ans)

E以降

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

参考にしたサイト等

脚注

*1 :103iから103(i+1)1までの自然数には, それぞれi個のコンマがつくということを表した式になります. 例えば, 1,000から999,999までの自然数には, コンマが1個つきます. 1,000,000から999,999,999までの自然数には, コンマが2個つきます.

*2 :APG4bのEX-22に, 多次元配列のソートに関連した問題があります.

Search

About Me

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

Labels

Blog Archives