AIZU ONLINE JUDGE ITP1_6_Dをpythonで解いてみた

python

本サイトAIZU ONLINE JUDGE ITP1_6_D へはこちらから

目次

問題:ベクトルと行列の積

\(n×m\) の行列 \(A\) と、\(m×1\) の列ベクトル \(b\) を読み込み、 \(A\) と \(b\) の積を出力するプログラムを作成してください。

次のように \(m\) 個の数を縦に並べたものを \(m×1\) の列ベクトルと呼びます。

$$b = \left( \begin{array}{c} b_1 \\ b_2 \\ : \\ b_m \\ \end{array} \right)$$

次のように \(n\) 個の数を含む列ベクトルを \(m\) 個横に並べたものを \(n×m\) の行列と呼びます。

$$A = \left( \begin{array}{cccc} a_{11} & a_{12} & … & a_{1m} \\ a_{21} & a_{22} & … & a_{2m} \\ : & : & : & : \\ a_{n1} & a_{n2} & … & a_{nm} \\ \end{array} \right)$$

ベクトルまたは行列の中に含まれる数のことを要素と呼び、\(m×1\) の列ベクトル \(b\) の上から \(i\) 番目の要素は \(b_i (i = 1,2,…, m)\) 、\(n×m\) の行列 \(A\) には \(n×m\) 個の要素が含まれ、 \(i\)行 \(j\) 列目の要素は \(a_{ij} (i = 1, 2, …, n, j = 1, 2, …, m)\) で示されます。

\(n×m\) の行列 \(A\) と \(m×1\) の列ベクトル \(b\) の積は、 \(n×1\) の列ベクトル \(c\) となり、\(c\) の \(i\) 番目の要素 \(c_i\) は次の式で得られます:

$$c_i = \sum_{j=1}^m a_{ij}b_j = a_{i1}b_1 + a_{i2}b_2 + … + a_{im}b_m$$

Input

1行目に \(n\) と \(m\) が空白区切りで与えられます。続く \(n\) 行に行列 \(A\) の要素 \(a_{ij}\) が空白区切りで与えられます。続く \(m\) 行にベクトル \(b\) の要素 \(b_i\) がそれぞれ1行に与えられます。

Constraints

  • 1≤ \(n\) ,\(m\)≤100
  • 0≤\(b_i\) ,\(a_{ij}\) ≤1000

Output

出力は \(n\) 行からなります。ベクトル \(c\) の要素 \(c_i\) をそれぞれ1行に出力してください。

Sample Input

3 4
1 2 0 1
0 3 0 1
4 1 1 0
1
2
3
0

Sample Output

5
6
9

解答例

n, m = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(n)]
b = [int(input()) for _ in range(m)]

for i in range(n):
    sum = 0
    for j in range(m):
        sum += A[i][j] * b[j]
    print(sum)

解説

以下のように解いていきます。

  1. 2つの整数(\(n\),\(m\))の読み込み
  2. \(n×m\) の行列の読み込み
  3. \(m×1\) の列ベクトルの読み込み
  4. ベクトルと行列の積の表示

ここではmap関数を使用します。第二引数のinput().split()で空白区切りの文字列を取得した値を、一つずつint関数に当てはめてint型に変換、(\(n\)、\(m\))に設定していきます。

# input().split()で空白区切りの文字列を取得 → intに変換 → n, m に設定
n, m = map(int, input().split())

※サイト内「AIZU ONLINE JUDGE ITP1_1_Cをpythonで解いてみた」の、map関数とはにmap関数の使用方法が書かれておりますのでぜひご覧ください。

まず、map関数を使用し、m個の数字の入力を行います。第二引数のinput().split()で空白区切りの文字列を取得した値を、一つずつint関数に当てはめてint型に変換、さらに、list関数で囲みます。

続いて、for文のイテラブルにrange(n)を設定し、m個の数字の入力処理であるlist(map(int, input().split()))をn回行います。

これでm個の数字のかたまりが、n個のリストが作成されます。

# input().split()で空白区切りの文字列を取得 → intに変換 → list関数で囲み、リストとしてm個の数値を受け取る
# さらに【for _ in range(n)】でm個の数値の受け取りをn回行う
A = [list(map(int, input().split())) for _ in range(n)]

※サイト内「AIZU ONLINE JUDGE ITP1_6_Bをpythonで解いてみた」の、リスト内包表記とはにリスト内包表示の使用方法が書かれておりますのでよかったらご覧ください。

Sample Inputを例にすると以下のようにリストに設定されます。

# 入力
3 4
1 2 0 1
0 3 0 1
4 1 1 0

# 4個のリスト読み込みを3回繰り返し、リストに設定
[[1, 2, 0, 1], [0, 3, 0, 1], [4, 1, 1, 0]]

これも、2. \(n×m\) の行列の読み込みと同様に1つの整数の入力をm回繰り返し、リストに設定します。

# 1つの整数の入力をm回繰り返す
b = [int(input()) for _ in range(m)]

Sample Inputを例にすると以下のようにリストに設定されます。

# 入力
1
2
3
0

# 1つの整数の入力をm回繰り返し、リストに設定
[1, 2, 3, 0]

2、3で取得した行列とベクトルの積を表示します。

行列の積は以下のように求められます。

$$\begin{pmatrix}a & b \\\end{pmatrix} \begin{pmatrix}p & q \\r & s \\\end{pmatrix} = \begin{pmatrix}ap + br & aq+bs \\\end{pmatrix}$$

Sample Inputを例にすると以下のようになります。

# 列ベクトル
1
2
3
0

# 行列
1 2 0 1
0 3 0 1
4 1 1 0

# 列ベクトル × 行列 イメージ①
列ベクトル[1, 2, 3, 0] × 行列[[1, 2, 0, 1], [0, 3, 0, 1], [4, 1, 1, 0]]

# 列ベクトル × 行列 イメージ②
[1, 2, 3, 0] × [1, 2, 0, 1] = 5
[1, 2, 3, 0] × [0, 3, 0, 1] = 6
[1, 2, 3, 0] × [4, 1, 1, 0] = 9

# 列ベクトル × 行列 イメージ③
1×1 + 2×2 + 3×0 + 0×1 = 5
1×0 + 2×3 + 3×0 + 0×1 = 6
1×4 + 2×1 + 3×1 + 0×0 = 9

今回は2つのfor文を使用し、行列Aのi番目の各要素と列ベクトルbの要素の総和を求めて表示をn回繰り返します。

for i in range(n):
    # sumをリセット
    sum = 0
    for j in range(m):
        # 行列のi番目の要素のj番目 × 列ベクトルのj番目 を足し合わせる
        sum += A[i][j] * b[j]
    # 総和を表示
    print(sum)

最後に、もう一度プログラムを確認してみましょう。

# input().split()で空白区切りの文字列を取得 → intに変換 → n, m に設定
n, m = map(int, input().split())
# input().split()で空白区切りの文字列を取得 → intに変換 → list関数で囲み、リストとしてm個の数値を受け取る
# さらに【for _ in range(n)】でm個の数値の受け取りをn回行う
A = [list(map(int, input().split())) for _ in range(n)]
# 1つの整数の入力をm回繰り返す
b = [int(input()) for _ in range(m)]

for i in range(n):
    # sumをリセット
    sum = 0
    for j in range(m):
        # 行列のi番目の要素のj番目 × 列ベクトルのj番目 を足し合わせる
        sum += A[i][j] * b[j]
    # 総和を表示
    print(sum)
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

雇われのシステムエンジニアです。
普段は車載ECUのセキュリティー分野に従事しております。

■保有資格
Salesforce 認定 Platform アプリケーションビルダー
Salesforce 認定 Platform デベロッパー

コメント

コメントする

目次