[백준 문제풀이] 2839번 설탕 배달


2839번 설탕 배달 (Bronze 1)

문제

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

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.

상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.

상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오.

첫째 줄에 N이 주어진다. (3 ≤ N ≤ 5000)

상근이가 배달하는 봉지의 최소 개수를 출력한다. 만약, 정확하게 N킬로그램을 만들 수 없다면 -1을 출력한다.

풀이

N이 5000까지이기 때문에 단순 반복 계산은 아닐거라고 생각했다.

! 아이디어
나머지와 몫을 사용하면 간단히 풀 수 있지 않을까? 5키로그램 봉지를 최대한 많이 가져가면 가져갈 봉지가 줄어든다.

3의 봉지와 5의 봉지를 반복문 없이 계산할 수 있지 않을까 했는데 어려웠다.

5로 나누어서 나머지가 0이 된다면 제일 적은 봉지 수이기 때문에 반복문에 첫 부분에 조건문으로 넣어주고, 총 무게에서 3을 계속 빼어서 count를 통해 3키로 봉지를 세어서 남은 무게를 5로 나눈 것과 더해주었다.

나중에 알고보니 이게 그리디 알고리즘이었다더라.


[백준 문제풀이] 2775번 부녀회장이 될테야


2775번 부녀회장이 될테야 (Bronze 1)

문제

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

평소 반상회에 참석하는 것을 좋아하는 주희는 이번 기회에 부녀회장이 되고 싶어 각 층의 사람들을 불러 모아 반상회를 주최하려고 한다.

이 아파트에 거주를 하려면 조건이 있는데, “a층의 b호에 살려면 자신의 아래(a-1)층의 1호부터 b호까지 사람들의 수의 합만큼 사람들을 데려와 살아야 한다” 는 계약 조항을 꼭 지키고 들어와야 한다.

아파트에 비어있는 집은 없고 모든 거주민들이 이 계약 조건을 지키고 왔다고 가정했을 때, 주어지는 양의 정수 k와 n에 대해 k층에 n호에는 몇 명이 살고 있는지 출력하라. 단, 아파트에는 0층부터 있고 각층에는 1호부터 있으며, 0층의 i호에는 i명이 산다.

제한 시간 : 1초

제한 : 1 ≤ k, n ≤ 14

첫 번째 풀이

제한과 시간을 봤을 때, 각 층이 올라갈때마다 바로 아래층과 이전 방의 값을 더해서 배열로 만들어주는 것으로 구현이 가능할 수 있겠다고 생각했다.

틀림.

두 번째 풀이

자꾸 에러가 나서 2일 동안 고민했는데, 알고보니까 사례 수는 층, 호수를 전부 포함하는 것이라서 반복문을 T번 더 해주어야했다. 어썸 코딩… (2021.11.12.)

풀이 이후 자꾸 에러가 나서 서치를 해봤는데, 이 문제의 아래에 전부 1로된 층을 추가한 뒤, 파스칼의 삼각형으로 접근, 이항정리 문제로 푸는 방법을 찾았다. 오늘도 어썸 코딩.

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const fs = require("fs");

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

const T = parseInt(input[0]);

for (let i = 1; i < T * 2; i = i + 2) {
  const k = parseInt(input[i]);
  const n = parseInt(input[i + 1]);
  const apartment = [];

  for (let l = 0; l <= k; l++) {
    apartment.push([1]);
    for (let j = 1; j < n; j++) {
      if (l === 0) {
        apartment[l].push(j + 1);
      } else {
        apartment[l].push(apartment[l - 1][j] + apartment[l][j - 1]);
      }
    }
  }
  console.log(apartment[k][n - 1]);
}

[백준 문제풀이] 10757번 큰 수 A + B


10757번 큰 수 A + B (Bronze 5)

배운 것

문제는 간단했는데, js에서 처리할 수 있는 수에 한계가 있어서 BigInt라는 자료형이 있다는 것을 알게 되었다. BigInt는 끝에 n이 붙기 때문에 string으로 변환해서 출력해주어야한다.

문제

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

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.


[백준 문제풀이] 2869번 달팽이는 올라가고 싶다


2869번 달팽이는 올라가고 싶다 (Bronze 1)

문제

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

땅 위에 달팽이가 있다. 이 달팽이는 높이가 V미터인 나무 막대를 올라갈 것이다.

달팽이는 낮에 A미터 올라갈 수 있다. 하지만, 밤에 잠을 자는 동안 B미터 미끄러진다. 또, 정상에 올라간 후에는 미끄러지지 않는다.

달팽이가 나무 막대를 모두 올라가려면, 며칠이 걸리는지 구하는 프로그램을 작성하시오.

첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)

제한시간 : 0.15초

첫 번째 풀이

수가 크기 때문에 반복문을 사용하는 것은 불가능하고, 나눠서 해결하는 방식이라고 생각했다. 다음 날 낮에 올라가는 것까지 계산해야하기 때문에, 미리 낮에 올라가는걸 뺀 후 그 수를 넘는 때를 구하기로 했다.

25%에서 틀림.

두 번째 풀이

25%에서 틀렸다는 것은 예외처리가 잘 되지 못한 것 같다.

floor를 사용해서 문제를 풀었었는데, v – a의 값이 a보다 작으면 반내림을 사용하게 되면 오답이 나오게 되기 때문에 반올림을 사용해서 문제를 풀어야했다.


[백준 문제풀이] 10250번 ACM 호텔


10250번 ACM 호텔 (Bronze 3)

문제

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

ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와 줄 프로그램을 작성하고자 한다. 즉 설문조사 결과 대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다.

문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정하자 (1 ≤ H, W ≤ 99). 그리고 엘리베이터는 가장 왼쪽에 있다고 가정하자(그림 1 참고). 이런 형태의 호텔을 H × W 형태 호텔이라고 부른다. 호텔 정문은 일층 엘리베이터 바로 앞에 있는데, 정문에서 엘리베이터까지의 거리는 무시한다. 또 모든 인접한 두 방 사이의 거리는 같은 거리(거리 1)라고 가정하고 호텔의 정면 쪽에만 방이 있다고 가정한다.

방 번호는 YXX 나 YYXX 형태인데 여기서 Y 나 YY 는 층 수를 나타내고 XX 는 엘리베이터에서부터 세었을 때의 번호를 나타낸다. 즉, 그림 1 에서 빗금으로 표시한 방은 305 호가 된다.

손님은 엘리베이터를 타고 이동하는 거리는 신경 쓰지 않는다. 다만 걷는 거리가 같을 때에는 아래층의 방을 더 선호한다. 예를 들면 102 호 방보다는 301 호 방을 더 선호하는데, 102 호는 거리 2 만큼 걸어야 하지만 301 호는 거리 1 만큼만 걸으면 되기 때문이다. 같은 이유로 102 호보다 2101 호를 더 선호한다.

여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1 의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다.

첫 번째 풀이

문제는 복잡해보이나, 결국 H를 N으로 나눈 몫 + 1이 호수가 되고, 나머지가 층 수가 된다. 각각을 구한뒤 문자열로 만들어 더 해준다.

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

const c = parseInt(input[0]);

for (let i = 1; i <= c; i++) {
  const line = input[i].split(" ");
  const h = parseInt(line[0]);
  const w = parseInt(line[1]);
  const n = parseInt(line[2]);
  const room = Math.ceil(n / h);
  let floor;
  let answer;

  if (n % h === 0) {
    floor = h;
  } else {
    floor = n % h;
  }

  if (room >= 10) {
    console.log(`${floor}${room}`);
  } else {
    console.log(`${floor}0${room}`);
  }
}