[백준] 행렬덧셈 2738, 최댓값 2566, 세로읽기 10798, 색종이 2563

이제훈·2024년 1월 2일

알고리즘

목록 보기
1/23

행렬덧셈 2738

크기가 같은 두개의 2차원 배열에서 같은 위치의 요소를 더하는 문제였다.
주의할 점은 입력값을 2차원 배열로 변환하고, 다시 문자열로 바꿔야 한다는 점과 각각 요소를 더할 때 문자열이 아니라 숫자로 변환하고 더해야 한다는 점이었다. 그리고 각 행과 열의 마지막에는 빈 칸을 추가하지 않아야 한다는 점도 있었다.

나의 풀이

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = fs.readFileSync(filePath).toString().trim().split("\n");
const [a, ...b] = input;
const [n, m] = a.split(" ");
const m1 = b.slice(0, n).map((v) => v.split(" ").map(Number));
const m2 = b.slice(n).map((v) => v.split(" ").map(Number));

let answer = "";
for (let i = 0; i < n; i++) {
  for (let j = 0; j < m; j++) {
    if (j === m - 1) {
      answer += m1[i][j] + m2[i][j];
    } else {
      answer += m1[i][j] + m2[i][j] + " ";
    }
  }
  if (i !== n - 1) {
    answer += "\n";
  }
}
console.log(answer);

나는 입력값을 2차원 배열로 바꿀 때부터 숫자로 타입을 바꿔주었다.
그리고 반복문으로 2차원 배열을 순회하면서 더한 값을 answer 변수에 추가해주는 식으로 문제를 풀었다.

최댓값 2566

2차원 배열을 순회하면서 최댓값이 바뀔 때마다 그 위치를 미리 선언한 변수에 저장해주는 식으로 문제를 풀었다.

나의 풀이

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = fs
  .readFileSync(filePath)
  .toString()
  .trim()
  .split("\n")
  .map((arr) => arr.split(" ").map(Number));

let max = Number.MIN_SAFE_INTEGER;
let row;
let col;

for (let i = 0; i < 9; i++) {
  for (let j = 0; j < 9; j++) {
    if (input[i][j] > max) {
      max = input[i][j];
      row = i + 1;
      col = j + 1;
    }
  }
}

console.log(max + "\n" + row + " " + col);

세로읽기 10798

길이가 다른 문자열을 요소로 갖는 배열을 열 -> 행 순서로 순회하는 문제였다.
다만, 문자열의 길이가 각각 다르기 때문에 가장 긴 문자열을 미리 찾아주는 식으로 문제를 풀었다.

문제를 풀면서 reduce 함수를 사용할 때 reduce가 반환하는 값이 다음에 참조하는 누적값이 된다는 점이 헷갈렸었다.

나의 풀이

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = fs.readFileSync(filePath).toString().trim().split("\n");

const n = input.length;
const m = input.reduce((acc, cur) => {
  if (cur.length > acc) {
    return cur.length;
  }
  return acc;
}, 0);

let answer = "";

for (let i = 0; i < m; i++) {
  for (let j = 0; j < n; j++) {
    if (input[j][i]) {
      answer += input[j][i];
    }
  }
}

console.log(answer);

색종이 2563

처음에 문제를 제대로 읽지 않아서? 아니면 문제를 제대로 이해하지 못해서 헤맸다. 색종이의 넓이는 10x10로 고정이고 붙인 위치만 입력값으로 주어진다. 입력값으로 주어진 자연수는 원점에서 가장 가까운 색종이를 붙인 좌표라고 이해했다. 그리고 거기에 10을 더한 좌표까지 색종이가 덮어씌어진 넓이가 된다.

체크 배열을 만들어서 각 색종이를 더할 때 한번 더한 곳이면 체크 배열에 체크를 하고 다음에 똑같은 색종이가 덮어질 때는 넓이를 더하지 않는 식으로 문제를 풀었다.

나의 풀이

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = fs.readFileSync(filePath).toString().trim().split("\n");

const [n, ...arr] = input;
const check = Array.from({ length: 100 }, () => Array(100).fill(false));
const papers = arr.map((v) => v.split(" ").map(Number));

let answer = 0;
for (const [x, y] of papers) {
  for (let i = x; i < x + 10; i++) {
    for (let j = y; j < y + 10; j++) {
      if (!check[i][j]) {
        check[i][j] = true;
        answer++;
      }
    }
  }
}

console.log(answer);

출처:
행렬덧셈 https://www.acmicpc.net/problem/2738
최댓값 https://www.acmicpc.net/problem/2566
세로읽기 https://www.acmicpc.net/problem/10798
색종이 https://www.acmicpc.net/problem/2563

0개의 댓글