안녕하세요

[node.js] 기본 수학 단계 (자바스크립트) 1712 ~ 본문

백준 자바스크립트

[node.js] 기본 수학 단계 (자바스크립트) 1712 ~

sakuraop 2022. 5. 12. 23:08

클론코딩을 하면서 부족한 자바스크립트 문법은 백준을 통해서 공부합시다.

초보입니다. 코드 설명은 "참고만" 해주세요.

https://www.acmicpc.net/step/8

 

문자열 단계

정수를 문자열로 입력받는 문제. Python처럼 정수 크기에 제한이 없다면 상관 없으나, 예제 3은 일반적인 정수 자료형에 담기에 너무 크다는 점에 주목합시다.

www.acmicpc.net


1712 손익분기점

아래와 같이 A만원의 고정 비용, B만원의 가변 비용, 제품 책정 가격 C만원을 입력받습니다. 제품의 판매량에 따라 총 수입이 총 비용보다 많아져 이익이 발생하는 손익분기점을 구하시오.

1000 70 170

총 11대를 팔아야 손익분기점을 넘습니다.

11

제출한 답 - 손익분기점 공식 : 고정비 / (1-변동비/매출액) 

const [a, b, c] = require("fs").readFileSync("dev/stdin").toString().split(" ").map(Number);

b < c ? console.log(Math.floor(a / (c - b)) + 1) : console.log(-1);

코드 설명 - 삼항연산자

  • b < c 
    b가 c보다 작은가
  • ? console.log(Math.floor(a / (c - b)) + 1)
    그렇다면 console.log(Math.floor(a / (c - b)) + 1) 를 실행합니다.
  • : console.log(-1);
    그렇지 않다면 console.log(-1); 를 실행합니다.

2292 벌집

아래와 같이 숫자 N이 주어졌을 때, 위의 규칙에 따라 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.

13

결과

3

제출한 답 - 바깥 방으로 갈 수록 방은 6*i 개 늘어납니다.

const n = require("fs").readFileSync("dev/stdin").toString();


let mass = 1;
let roomCount = 0;

while (roomCount < n - 1) {
  roomCount += 6 * mass;
  mass++;
}

console.log(mass);

코드 설명

  • while (roomCount < n - 1)
    정중앙에 1칸의 방이 있기 때문에 n - 1 보다 방의 갯수가 작다면 반복합니다.
  • roomCount += 6 * mass;
    방의 갯수는 (지금까지 존재하는 방의 갯수) + (6배수) 로 늘어납니다.
  •   mass++;
    중앙에서 바깥으로 한 칸씩 이동할 때마다 1 을 더합니다. 

1193 분수찾기

무한히 큰 배열에 다음과 같이 분수들이 적혀있다.

1/1 1/2 1/3 1/4 1/5
2/1 2/2 2/3 2/4
3/1 3/2 3/3
4/1 4/2
5/1

이와 같이 나열된 분수들을 1/1 → 1/2 → 2/1 → 3/1 → 2/2 → … 과 같은 지그재그 순서로 차례대로 1번, 2번, 3번, 4번, 5번, … 분수라고 하자.

X가 주어졌을 때, X번째 분수를 구하는 프로그램을 작성하시오.

입력

14

결과

2/4

제출한 답

let x = Number(require("fs").readFileSync("dev/stdin").toString());

let count = 0;
let round = 0;

while (count < x) {
  round++;
  count = count + round;
}

if (round % 2 == 1) {
  console.log(`${count - x + 1}/${-count + x + round}`);
} else {
  console.log(`${-count + x + round}/${count - x + 1}`);
}

코드 설명

  • while (count < x) {
      round++;
      count = count + round;
    }
  • round
    분자와 분모의 합이 같은 배열끼리 모아 놓은 순번입니다.
    (1/2, 2/1가 들어있는 두번째 배열의 경우 분자와 분모의 합은 3입니다.)
    round는 배열에 속하는 분자와 분모의 합보다 1 작습니다.
  • count
    첫 수부터 round에 속한 마지막 수까지의 갯수를 가리킵니다.
    11<=x<=15 라면 count는 15가 됩니다.
  • count - x + 1 / -count + x + round 
    x는 입력하는 값에 따라 변화합니다. x를 기준으로 분자와 분모를 증가 또는 감소하도록 합니다.

2869 달팽이는 올라가고 싶다

V미터를 A미터만큼 오른 뒤에, B미터만큼 내려갑니다. V미터에 도달하는 데에 걸리는 시간을 구하시오.

아래와 같이 A, B, V가 공백으로 구분되어서 주어집니다.

100 99 1000000000

결과

999999901

제출한 답

const [a, b, v] = require("fs").readFileSync("dev/stdin").toString().split(" ").map(Number);

console.log(Math.ceil((v - b) / (a - b)));

코드 설명

  • 입력값과 결과값을 살펴보면 간단하게 구할 수 있는 값이었습니다.

10250 ACM 호텔

101~H01, 102~H02 ... 10W~H0W 까지 순서대로 빈칸을 채웁니다. 빗금이 쳐진 칸을 N이라 합니다. N을 구하시오. 아래와 같이 첫 줄에 테스트케이스의 수, H, W, N 을 입력 받습니다.

2
6 12 10
30 50 72

결과

402
1203

제출한 답

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

for (i = 1; i <= input[0]; i++) {
  let [h, w, n] = input[i].split(" ");
  for (j = 1; j <= h * w; j++) {
    if (n == j) {
      let y = `${n % h}`;
      if (n % h == 0) {
        y = h;
      }
      let x = `${Math.ceil(j / h)}`;
      if (x.length == 1) {
        x = `0${x}`;
      }
      console.log(y + x);
    }
  }
}

코드 설명

  • .split("\n").map((x) => x.trim())
    입력받은 문자열에 '\r'가 포함되어 있어 trim으로 제거합니다.
  • for (i = 1; i <= input[0]; i++) {
      let [h, w, n] = input[i].split(" ");
    h,w,n 변수를 만들어 입력받은 테스트 케이스마다 반복합니다.
  •  for (j = 1; j <= h * w; j++) {
        if (n == j) {
    h*w (6 x 12) 만큼 반복할 것이지만 n에 해당하는 값만을 찾아서 출력할 것입니다.
  •   let y = `${n % h}`;
          if (n % h == 0) {
            y = h;
    n을 h로 나눈 나머지가 층수(y)가 됩니다.
  •  let x = `${Math.ceil(n / h)}`;
    n을 h로 나눈 값이 호실의 뒷자리 수(x)가 됩니다.
  •       if (x.length == 1) {
            x = `0${x}`;
    호실의 뒷자리 수가 1자리 수라면 "0x" 형태로 출력합니다.

 

제출한 답 2 - 삼항연산자 연습

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

for (i = 1; i <= input[0]; i++) {
  let [h, w, n] = input[i].split(" ");
  for (j = 1; j <= h * w; j++) {
    if (n == j) {
      let y = "";
      y = n % h == 0 ? (y = h) : (y = `${n % h}`);

      let x = `${Math.ceil(n / h)}`;
      if (x.length == 1) {
        x = `0${x}`;
      }

      console.log(y+x);
    }
  }
}

코드 설명

  • if-else 형태라면 삼항연산자를 적용할 수 있도록 해봅시다.

2775 부녀회장이 될테야

문제를 보자마자 필요한 열쇠는 배열이라 생각했습니다.

분명히 배열을 만들면 쉽게 해결이 될 것 같은데, 배열을 혼자서 아무리 만들어 보려고 해도 실패했습니다.

그렇다고 해서 답을 보기는 싫었기 때문에 유튜브에 자바스크립트 2차원 배열을 검색해보았습니다.

https://www.youtube.com/watch?v=tMeDkp1J2OM 

자바스크립트로 2차원 배열 만들기

아주 친절한 영상을 발견했습니다. 쉽고 간단하게 2차원 배열을 만드는 방법이 무려 4가지나 있습니다. 

첫 번째 방법이 직관적이기 때문에 첫 번째 방법을 이용했습니다.

const rows = 5;
const columns = 6;
const array = [];

for (i = 0; i < rows; i++) {
  array[i] = [];
}
console.log(array);

우선 rows를 생성합니다.

array의[i]번째 인덱스에  []를 5개 추가합니다.


[ [], [], [], [], [] ]
 
for (i = 0; i < rows; i++) {
  array[i] = [];
  for (j = 0; j < columns; j++) {
    array[i][j] = j;
  }
}
console.log(array);
 
columns를 만들어줄 차례입니다.
array[i] 는 각각의 []를 의미합니다. 
array[0] 는 첫 번째 []를 가리킵니다.   [ 0, 1, 2, 3, 4, 5 ],
array[0][j] 첫 번째 [0]의 [j]인덱스에 j(column)를 순서대로 넣습니다.
array[i] -> array[0, 1, 2, 3, 4, 5] 순서대로 순회하며 j를 넣게 되면 다음과 같이 출력됩니다.
[
  [ 0, 1, 2, 3, 4, 5 ],
  [ 0, 1, 2, 3, 4, 5 ],
  [ 0, 1, 2, 3, 4, 5 ],
  [ 0, 1, 2, 3, 4, 5 ],
  [ 0, 1, 2, 3, 4, 5 ]
]

“a층의 b호에 살려면 자신의 아래(a-1)층의 1호부터 b호까지 사람들의 수의 합만큼 사람들을 데려와 살아야 한다”

주어지는 양의 정수 k와 n에 대해 k층에 n호에는 몇 명이 살고 있는지 출력하라. 단, 아파트에는 0층부터 있고 각층에는 1호부터 있으며, 0층의 i호에는 i명이 산다.

아래와 같이 첫줄에 T를 이후로 k, n ,k ,n 을 번갈아 입력받습니다.

2
1
3
2
3

결과

6
10

제출한 답

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

let array = [];

for (i = 0; i < input[0]; i++) {
  let count = 0;
  let columns = input[2 * i + 1];
  let rows = input[2 * i + 2];
  for (j = 0; j <= columns; j++) {
    array[j] = [];
    for (l = 0; l < rows; l++) {
      if (j == 0) {
        count++;
        array[j][l] = count;
      }
      if (j >= 1) {
        if (l == 0) {
          array[j][l] = 1;
        } else {
          array[j][l] = array[j - 1][l] + array[j][l - 1];
        }
      }
    }
  }
  console.log(array[columns].slice(-1)[0]);
}

코드 설명

  • 배열 만드는 방법에 따라 r,c을 집어넣습니다.

  •       if (j == 0) {
    0층의 경우에는 1,2,3,4,5,... 1씩 증가하는 수열이므로 별도로 처리합니다.
  •       if (j >= 1) {
            if (l == 0) {
              array[j][l] = 1;
    1호의 모든 층은 1입니다.
  •         } else {
              array[j][l] = array[j - 1][l] + array[j][l - 1];
    나머지 호의 규칙은 (바로 아랫층 호실의 인원)과 (바로 이전 호실의 인원)을 합한 값입니다.

2839 설탕 배달

3 ≤ N ≤ 5000 에 대하여 N을 최대한의 5의 배수와 최소한의 3의 배수를 합한 조합으로 나머지가 생기지 않도록 나눕니다.

5와 3 각각의 배수를 더합니다. 나누어 떨어지지 않는다면 -1을 출력합니다.

18은 5x3 과 3x1로 이루어져 있습니다. 결과는 4입니다.

18

결과

4

 

제출한 답

let n = Number(require("fs").readFileSync("dev/stdin").toString());

let kg3 = 0;

while (n >= -2) {
  if (n % 5 == 0) {
    console.log(n / 5 + kg3);
    break;
  } else if (n < 0) {
    console.log(-1);
  }
  kg3++;
  n -= 3;
}

 

코드설명

  • 1) 최대한의 5kg 봉지와 최소한의 3kg 봉지를 조합하여 나누어 떨어지도록 해야합니다.
  • 2) 나누어 떨어지지 않는다면 3kg 만큼 덜어냅니다.
      kg3++;
      n -= 3;
  • 3) 5kg 봉지로 나누어떨어질 때까지 3kg 만큼 덜어내는 작업을 반복합니다.
    while (n >= -2) {
      if (n % 5 == 0) {
        console.log(n / 5 + kg3);
        break;
  • 4) 모두 덜어내었음에도 나누어떨어지지 않는다면 -1을 출력합니다.
      } else if (n < 0) {
        console.log(-1);
      }

10757 큰 수 A+B

 

아래와 같이 큰 수 a,b를 입력 받아 a+b를 출력합니다.

9223372036854775807 9223372036854775808

결과

18446744073709551615

 

제출한 답

const [a, b] = require("fs").readFileSync("dev/stdin").toString().split(" ").map(BigInt);

console.log((a + b).toString());

 

코드설명

  • .map(BigInt)
    자바스크립트는 정수형의 수는 2^53-1 까지만 온전하게 저장할 수 있습니다. 
    이보다 큰 수의 경우에는 숫자 끝에 'n'을 붙여 100n과 같은 형태로 만들면 되는데 BigInt() 함수를 이용하면 됩니다.
    100n 은 BitInt(100) 과 같습니다.
  • console.log((a + b).toString());
    결과값인 18446744073709551615n 의 typeof 함수의 출력값은 bigint 입니다.
    BigInt를 나타내는 n을 없애기 위해서는 toString() 함수를 이용합니다.
    18446744073709551615n 을 toStirng()으로 변환하게 되면 type이 string으로 변하면서 n 이 사라집니다.

    +
let bbb = 123n;
console.log(typeof bbb);
>> bigint
VSCode에서 123n 을 입력해 보면 n 이 다른 색상으로 처리가 된 것을 볼 수 있습니다.

기본 수학 단계 1은 여기까지입니다.