본문 바로가기
JS/백준

[백준/nodeJS] 2740. 행렬 곱셈

by GiraffePark 2023. 12. 29.

안녕하세요. 박기린입니다.

백준 2740번 행렬 곱셈 문제 풀어보겠습니다.

 

 


문제 링크

https://www.acmicpc.net/problem/2740

 

 

 


문제 해석

행렬 곱셈에 대해 사전 지식이 있다면 쉽게 폴 수 있습니다.

하지만 그렇지 못한 분도 있기에 간단하게 설명해보겠습니다.

 

문제에서 예시 입력으로 주어진 두 개의 행렬입니다.

[3 * 2] 와 [2 * 3]으로 이루어진 행렬이고, N은 3, M은, K는 3입니다.

 

행렬의 크기는 N * K로 구할 수 있기 때문에, [3 * 3]임을 미리 알고 시작합니다.

 

 

 

 

N과 K가 1일 때의 값을 구해보겠습니다.

 

이때 행렬 곱셈 방법은 이러합니다.

1. 첫 번째 행렬에서 N이 1인 행을 찾습니다.
2. 두 번째 행렬에서 K가 1인 열을 찾습니다.
3. 행일 경우 맨 왼쪽, 열일 경우 맨 위쪽에서부터 차례대로 곱한 값을 더합니다.
4. 그렇게 모인 값이 행렬곱의 결과물이 됩니다.

계산 식 : 1 * (-1) + 2 * 0 = -1

 

 

 

N과 K가 2일 때의 값을 구해보겠습니다.

 

이때 행렬 곱셈 방법은 이러합니다.

1. 첫 번째 행렬에서 N이 2인 행을 찾습니다.
2. 두 번째 행렬에서 K가 2인 열을 찾습니다.
3. 행일 경우 맨 왼쪽, 열일 경우 맨 위쪽에서부터 차례대로 곱한 값을 더합니다.
4. 그렇게 모인 값이 행렬곱의 결과물이 됩니다.

계산 식 : 3 * (-2) + 4 * 0 = -6

 

 

 

N과 K가 3일 때도 동일하게 계산해주면 됩니다.

계산 식 : 5 * 0 + 6 * 3 = 18

 

 

 

 

반복문을 이용해서 모든 행렬이 곱을 구해주고 출력하면 끝입니다.

 

 

 

 

 


정답 코드

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

const firstMatrix = [];
const secondMatrix = [];

let cursor = 0;
const [aN, aM] = input[cursor++].split(" ").map(Number);

for (let i = 0; i < aN; i++) {
  firstMatrix.push(input[cursor++].split(" ").map(Number));
}

const [bM, bK] = input[cursor++].split(" ").map(Number);

for (let i = 0; i < bM; i++) {
  secondMatrix.push(input[cursor++].split(" ").map(Number));
}

const N = aN;
const M = aM; // (=== bM)
const K = bK;

const resultMatrix = Array.from(Array(N), () => new Array(K).fill(0));

for (let n = 0; n < N; n++) {
  for (let m = 0; m < M; m++) {
    for (let k = 0; k < K; k++) {
      resultMatrix[n][k] += firstMatrix[n][m] * secondMatrix[m][k];
    }
  }
}

console.log(resultMatrix.map((e) => e.join(" ")).join("\n"));

 

 

 

 


정답 코드 풀이

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

const firstMatrix = [];
const secondMatrix = [];

let cursor = 0;
const [aN, aM] = input[cursor++].split(" ").map(Number);

for (let i = 0; i < aN; i++) {
  firstMatrix.push(input[cursor++].split(" ").map(Number));
}

const [bM, bK] = input[cursor++].split(" ").map(Number);

for (let i = 0; i < bM; i++) {
  secondMatrix.push(input[cursor++].split(" ").map(Number));
}

cursor 변수를 이용해서 입력받은 값을 접근합니다.

aN과 aM은 N과 M, bM과 bK는 M과 K값을 각각 가집니다.

firstMatrix에 첫 번째 행렬, secondMatrix에 두 번째 행렬을 저장합니다.

 

 

 

const N = aN;
const M = aM; // (=== bM)
const K = bK;

const resultMatrix = Array.from(Array(N), () => new Array(K).fill(0));

aN, aM(bM), bK를 N, M. K로 다시 저장합니다. (보기 쉽게 하기 위함.)

그리고 [N * K] 형태의 행렬(resultMatrix)을 만듭니다. 여기에 행렬곱의 결과값들을 담을 예정입니다.

 

 

 

 

for (let n = 0; n < N; n++) {
  for (let m = 0; m < M; m++) {
    for (let k = 0; k < K; k++) {
      resultMatrix[n][k] += firstMatrix[n][m] * secondMatrix[m][k];
    }
  }
}

3중 for문으로 n, m, k를 모두 접근합니다.

위의 문제해석 섹션에서 설명드린 내용을 구현한 코드입니다. 

n, m, k의 for문 순서는 달라져도 상관없습니다.

 

 

 

console.log(resultMatrix.map((e) => e.join(" ")).join("\n"));

마지막으로, 계산한 행렬곱 값을 조건에 맞게 출력하면 끝입니다.

 

반응형