문제
문제: <그림 1>과 같이 9×9 격자판에 쓰여진 81개의 자연수 또는 0이 주어질 때, 이들 중 최댓값을 찾고 그 최댓값이 몇 행 몇 열에 위치한 수인지 구하는 프로그램을 작성하시오.
예를 들어, 다음과 같이 81개의 수가 주어지면
1열 | 2열 | 3열 | 4열 | 5열 | 6열 | 7열 | 8열 | 9열 | |
1행 | 3 | 23 | 85 | 34 | 17 | 74 | 25 | 52 | 65 |
2행 | 10 | 7 | 39 | 42 | 88 | 52 | 14 | 72 | 63 |
3행 | 87 | 42 | 18 | 78 | 53 | 45 | 18 | 84 | 53 |
4행 | 34 | 28 | 64 | 85 | 12 | 16 | 75 | 36 | 55 |
5행 | 21 | 77 | 45 | 35 | 28 | 75 | 90 | 76 | 1 |
6행 | 25 | 87 | 65 | 15 | 28 | 11 | 37 | 28 | 74 |
7행 | 65 | 27 | 75 | 41 | 7 | 89 | 78 | 64 | 39 |
8행 | 47 | 47 | 70 | 45 | 23 | 65 | 3 | 41 | 44 |
9행 | 87 | 13 | 82 | 38 | 31 | 12 | 29 | 29 | 80 |
이들 중 최댓값은 90이고, 이 값은 5행 7열에 위치한다.
입력: 첫째 줄부터 아홉 번째 줄까지 한 줄에 아홉 개씩 수가 주어진다. 주어지는 수는 100보다 작은 자연수 또는 0이다.
출력: 첫째 줄에 최댓값을 출력하고, 둘째 줄에 최댓값이 위치한 행 번호와 열 번호를 빈칸을 사이에 두고 차례로 출력한다. 최댓값이 두 개 이상인 경우 그 중 한 곳의 위치를 출력한다.
예제 입력:
3 23 85 34 17 74 25 52 65
10 7 39 42 88 52 14 72 63
87 42 18 78 53 45 18 84 53
34 28 64 85 12 16 75 36 55
21 77 45 35 28 75 90 76 1
25 87 65 15 28 11 37 28 74
65 27 75 41 7 89 78 64 39
47 47 70 45 23 65 3 41 44
87 13 82 38 31 12 29 29 80
예제 출력:
90
5 7
과정
const matrix = [
[3, 23, 85, 34, 17, 74, 25, 52, 65],
[10, 7, 39, 42, 88, 52, 14, 72, 63],
[87, 42, 18, 78, 53, 45, 18, 84, 53],
[34, 28, 64, 85, 12, 16, 75, 36, 55],
[21, 77, 45, 35, 28, 75, 90, 76, 1],
[25, 87, 65, 15, 28, 11, 37, 28, 74],
[65, 27, 75, 41, 7, 89, 78, 64, 39],
[47, 47, 70, 45, 23, 65, 3, 41, 44],
[87, 13, 82, 38, 31, 12, 29, 29, 80]
];
const flat = matrix.flat().map(Number);
console.log(flat,'flat')
const maxNum = Math.max.apply(null,flat);
console.log(maxNum,'maxNum');
let row = 0, col = 0;
for(let i = 0; i<9; i++){
for(let j = 0; j<9; j++){
if(matrix[i][j]===maxNum){
row= i+1;
col=j+1;
}
}
}
console.log(maxNum);
console.log(`${row} ${col}`);
정답 코드
const fs = require('fs');
const input = fs.readFileSync(0, 'utf-8').trim().split('\n');
// 2차원 배열로 숫자 저장
const matrix = input.map(line => line.split(' ').map(Number));
// flat() 사용해서 모든 숫자를 하나의 배열로 만듦
const flat = matrix.flat();
// 최댓값 구하기
const maxNum = Math.max.apply(null, flat);
// 위치 찾기
let row = 0, col = 0;
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (matrix[i][j] === maxNum) {
row = i + 1;
col = j + 1;
}
}
}
console.log(maxNum);
console.log(`${row} ${col}`);
코드 해석 ( Math.max.apply() 사용 )
(2차원 배열에서 모든 숫자들을 1차원 배열로 펼쳐서 최댓값을 구한 후 그 값의 index를 찾는다.
1. 백준입력을 split('\n')을 사용하여 줄바꿈 단위로 나누어 input에 저장한다.
2. input 배열의 각 줄을 split(' ')으로 띄어쓰기 기준으로 나눈 후, map(Number)를 사용해 문자열을 숫자로 변환하여 2차원 숫자 배열인 matrix를 만든다.
3. matrix를 flat()을 사용하여 하나의 배열로 만든다. 다시 1차원 배열이 된다.
4. 1차원 배열에서 Math.max.apply()를 사용하여 최댓값을 찾아 변수 maxNum에 저장한다.
5. 행과 열을 저장할 변수 row와 col을 선언한다.
6. 2중for문으로 원본배열인 2차원배열 matrix배열에서 최댓값 maxNum 와 일치하는지 찾는다.
7. 일치한다면 i는 행 변수 row에, j는 열 변수 col에 각각 +1씩 더하여 저장한다.
8. 출력기준에 맞춰서 출력한다.
더 알아보기
1. 최적코드(gpt추천, apply와flat을 사용하지 않는 코드)
const fs = require('fs');
const input = fs.readFileSync(0, 'utf-8').trim().split('\n');
// 최댓값과 위치 초기화
let max = 0;
let row = 0;
let col = 0;
for (let i = 0; i < 9; i++) {
const line = input[i].split(' ').map(Number);
for (let j = 0; j < 9; j++) {
if (line[j] > max) {
max = line[j];
row = i + 1;
col = j + 1;
}
}
}
console.log(max);
console.log(`${row} ${col}`);
- 직관적이고 가독성이 좋다.
- 안정적이다.
- 기초적인 for문만 사용하여 백준 초보~중급자에게 가장 추천하는 방식이다.
- 반복문과 조건문 능력이 향상 되어 알고리즘을 푸는 연습에 좋다.
2. Modern JS버전 ( 짧고 깔끔하다)
const fs = require('fs');
const input = fs.readFileSync(0, 'utf-8').trim().split('\n');
const matrix = input.map(line => line.split(' ').map(Number));
const flat = matrix.flat();
const max = Math.max(...flat);
const { row, col } = matrix.reduce((acc, rowArr, i) => {
rowArr.forEach((num, j) => {
if (num === max) acc = { row: i + 1, col: j + 1 };
});
return acc;
}, { row: 0, col: 0 });
console.log(max);
console.log(`${row} ${col}`);
- flat으로 1차원 배열로 평탄화한다.
- Math.max(...flat) 스프레드 연산자로 최댓값을 계산한다.
- reduce와 forEach를 같이 사용하여 최댓값의 위치를 찾기위해 순회한다.(줄+칸 추적)
- row: i+1, col: j+1인 이유는 위치는 1부터 시작하므로 +1을 해준다.
*더 짧은 버전
코테나 실무에서 가독성+간결함을 모두 챙길 수 있는 스타일이다.
(주의! 너무 짧은 코드는 가독성을 해칠 수 있다.)
const fs = require('fs');
const input = fs.readFileSync(0, 'utf-8').trim().split('\n');
const matrix = input.map(r => r.split(' ').map(Number));
const max = Math.max(...matrix.flat());
let pos = [0, 0];
matrix.forEach((row, i) => {
row.forEach((val, j) => {
if (val === max) pos = [i + 1, j + 1];
});
});
console.log(max);
console.log(pos.join(' '));
정말 더더 짧은 버전!!! (Modern JS + 멋)
const fs = require('fs');
const input = fs.readFileSync(0, 'utf-8').trim().split('\n');
const matrix = input.map(line => line.split(' ').map(Number));
const { max, row, col } = matrix.reduce((acc, curRow, i) =>
curRow.reduce((innerAcc, val, j) =>
val > innerAcc.max ? { max: val, row: i + 1, col: j + 1 } : innerAcc
, acc)
, { max: -Infinity, row: 0, col: 0 });
console.log(max);
console.log(`${row} ${col}`);
이 코드는 reduce를 두 번 사용하여 바깥 reduce는 행을, 안쪽 reduce는 열을 순회한다.
조건문인 val>innerAcc.max로 최댓값과 위치를 동시에 갱신한다.
acc객체로 {max, row, col}을 한꺼번에 들고 다닌다.
시작값을 -Infinity를 넣어서 어떤 수라도 무조건 갱신이 된다.
실제로는 6줄이지만 1개의 reduce블록으로 모든 일 처리를 하기때문에 1개의 줄인것같은 느낌을 준다.
'알고리즘 Node.js' 카테고리의 다른 글
백준 2563문제. 색종이(어렵다,,,) (0) | 2025.04.02 |
---|---|
백준 10798문제. 세로읽기 (0) | 2025.04.01 |
백준 2738문제. 행렬 덧셈(2차원 배열 시작!) (0) | 2025.03.30 |
백준 25206문제. 너의 평점은 (0) | 2025.03.29 |
백준 1316문제. 그룹 단어 체커 (0) | 2025.03.28 |