안녕하세요. 박기린입니다.
백준 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"));
마지막으로, 계산한 행렬곱 값을 조건에 맞게 출력하면 끝입니다.
'JS > 백준' 카테고리의 다른 글
[백준/nodeJS] 14935. FA (0) | 2024.02.29 |
---|---|
[백준/nodeJS] 1016. 제곱 ㄴㄴ 수 (0) | 2024.01.26 |
[백준/nodeJS] 28279. 덱 2 (0) | 2023.12.21 |
[백준/JS] 12789. 도키도키 간식드리미 (1) | 2023.12.07 |
[백준/JS] 20920. 영단어 암기는 괴로워 (0) | 2023.12.02 |