本サイトAIZU ONLINE JUDGE ITP1_6_C へはこちらから
問題:公舎の入居者数
A大学は1フロア10部屋、3階建ての公舎4棟を管理しています。公舎の入居・退去の情報を読み込み、各部屋の入居者数を出力するプログラムを作成して下さい。
n件の情報が与えられます。各情報では、4つの整数b, f, r, vが与えられます。これは、b棟f階のr番目の部屋にv人が追加で入居したことを示します。vが負の値の場合、-v人退去したことを示します。
最初、全ての部屋には誰も入居していないものとします。
Input
最初の行に情報の数 n が与えられます。
続いて n 件の情報が与えられます。各情報には4つの整数 b, f, r, v が空白区切りで1行に与えられます。
Output
4棟について入居者数を出力して下さい。各棟について、1階、2階、3階の順に入居者数を出力します。各階については、1番目、2番目、・・・、10番目の部屋の入居者数を順番に出力します。入居者数の前には1つの空白を出力して下さい。また、各棟の間には####################(20個の#)で区切って下さい。
Constraints
- 間違った棟番号・階・部屋番号は与えられない。
- 管理の過程で1部屋の入居者数が0より少なくなることはない。
- 管理の過程で1部屋の入居者数が9より多くなることはない。
Sample Input
3
1 1 3 8
3 2 2 7
4 3 8 1
Sample Output
0 0 8 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
####################
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
####################
0 0 0 0 0 0 0 0 0 0
0 7 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
####################
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
解答例
houses = [[[0 for r in range(10)] for f in range(3)] for b in range(4)]
n = int(input())
for i in range(n):
b, f, r, v = map(int, input().split())
houses[b - 1][f - 1][r - 1] += v
for b in range(4):
for f in houses[b]:
print('', *f)
if b != 3:
print('#' * 20)
解説
以下のように解いていきます。
10部屋、3階建ての公舎4棟の組み合わせの作成
今回は、リスト内包表記をネストして、10部屋、3階建ての公舎4棟の組み合わせを数値0で作成します。
まず、[0 for r in range(10)]で[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]を作成、for f in range(3)でこれを3組作成し、for b in range(4)でこれらをさらに4組作成します。
# リスト内包表記をネストして10部屋、3階建ての公舎4棟の組み合わせを作成
houses = [[[0 for r in range(10)] for f in range(3)] for b in range(4)]
以下のような組み合わせが作成されます。
[[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]]
※サイト内「AIZU ONLINE JUDGE ITP1_6_Bをpythonで解いてみた」の、リスト内包表記とはにリスト内包表示の使用方法が書かれておりますのでよかったらご覧ください。
入居者数の入力
まずは、1つの整数の読み込みを行います。今回はこの入力された回数分、入居者数の入力を行います。
キーボードから文字列を受け取る際に使用するinput関数をint関数で囲み、1つの整数を読み込みます。
# input関数をint関数で囲み、整数値として変数に代入
n = int(input())
※※サイト内「AIZU ONLINE JUDGE ITP1_1_Bをpythonで解いてみた」の、input関数とはにinput関数の使用方法が書かれておりますのでぜひご覧ください。
続いて、先ほど入力された回数分、4つの整数b(棟), f(階), r(番目), v(人)の読み込みを行います。
まずは、for文のイテラブルにrange(n)を設定し、n回forループを回します。
続いて、for文内ではmap関数を使用し、複数の整数の読み込みを行います。第二引数のinput().split()で空白区切りの文字列を取得した値を、一つずつint関数に当てはめてint型に変換し、b(棟), f(階), r(番目), v(人)にそれぞれ設定します。
そして、1で作成した10×3×4の組み合わせの、b(棟), f(階), r(番目)にv(人)を設定します。
※配列は0から始まるため、指定する部屋は[b – 1][f – 1][r – 1]となります。作成時に全て0が設定されてあるので、指定の箇所にv(人)を設定するイメージです。
n = int(input())
for i in range(n):
# 4つの整数b(棟), f(階), r(番目), v(人)の読み込み
b, f, r, v = map(int, input().split())
# 全て0が設定されたリスト(houses)10×3×4の組み合わせのb(棟), f(階), r(番目)にv(人)を設定
houses[b - 1][f - 1][r - 1] += v
※サイト内「AIZU ONLINE JUDGE ITP1_1_Cをpythonで解いてみた」の、map関数とはにmap関数の使用方法が書かれておりますのでぜひご覧ください。
入居者数の出力
外側のfor文のイテラブルにrange(4)を設定し、0〜3の4つの数字が変数bに設定されます。
内側のfor文のイテラブルにhouses[b]を設定し、houses[0]〜houses[3]のb(棟)区切りの値のまとまりが変数fに設定されます。
表示にはprint関数の引数に(”, *f)を設定し、空白+houses[0]〜houses[3]のb(棟)区切りの値のまとまりが設定された変数fの中身が表示されます。
※データのまとまりの前にアスタリスク(*)を設定するとデータの中身が表示されます。
1棟の情報を全て表示したら、####################(20個の#)で区切ります。
※range(4)は0~3までの数字を順番に取り出すので、最後の3のときは区切りを表示しません。
for b in range(4):
# b(棟)の情報を表示
for f in houses[b]:
print('', *f)
# 区切り(####################)を表示
if b != 3:
print('#' * 20)
最後に、もう一度プログラムを確認してみましょう。
# リスト内包表記をネストして10部屋、3階建ての公舎4棟の組み合わせを作成
houses = [[[0 for r in range(10)] for f in range(3)] for b in range(4)]
# input関数をint関数で囲み、整数値として変数に代入
n = int(input())
for i in range(n):
# 4つの整数b(棟), f(階), r(番目), v(人)の読み込み
b, f, r, v = map(int, input().split())
# 全て0が設定されたリスト(houses)10×3×4の組み合わせのb(棟), f(階), r(番目)にv(人)を設定
houses[b - 1][f - 1][r - 1] += v
for b in range(4):
# b(棟)の情報を表示
for f in houses[b]:
print('', *f)
# 区切り(####################)を表示
if b != 3:
print('#' * 20)
コメント