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

 

1835번: 카드

첫 번째 줄에 카드의 개수 N(1 ≤ N ≤ 1,000)이 주어진다.

www.acmicpc.net

문제

1부터 N까지의 숫자가 적힌 카드가 있다. 찬유는 이 카드를 가지고 마술을 하려 한다. 마술을 하는 순서는 다음과 같다.

  1. 먼저 1부터 N까지의 숫자가 적힌 카드에서 첫 번째 카드를 가장 뒤로 옮긴다. 그러고 나서 첫 번째 카드를 책상 위에 올려놓는다. 그런데 그 카드는 1이 되어야 한다.
  2. 그리고 남은 카드 중에서 첫 번째 카드를 가장 뒤로 옮기고, 또 가장 앞에 있는 카드를 가장 뒤로 옮긴다.(2번 반복) 그리고 가장 앞에 있는 카드를 책상 위에 올려놓는다. 그런데 그 카드는 2가 되어야 한다.
  3. 또 남은 카드 중에서 첫 번째 카드를 가장 뒤로 옮기고... (3번 반복) 그리고 가장 앞에 있는 카드를 책상위에 올려놓는데 그것은 3이 된다.
  4. 또 남은 카드 중에서 첫 번째 카드를 가장 뒤로 옮기고.. (4번 반복) 그리고 가장 앞에 있는 카드를 책상 위에 올려놓는데 그것은 4이다.
  5. 위 과정을 계속 반복하여 N번 카드만 남을 때 까지 반복한다.

위와 같은 카드를 하려면 미리 카드의 순서를 알고 있어야 한다. 카드의 개수 N이 주어져 있을 때 위의 마술을 하기 위한 카드의 초기 순서를 구하는 프로그램을 작성하시오.

입력

첫 번째 줄에 카드의 개수 N(1 ≤ N ≤ 1,000)이 주어진다.

출력

첫 번째 줄부터 N번째 줄까지 차례로 카드의 순서를 출력한다.

예제 입력 1 복사

4

예제 출력 1 복사

2 1 4 3

 

문제풀이(1)

문제에 나와있는 방식을 반대로 진행하면 초기 카드의 세팅값을 찾을 수 있다.
1. N 번 카드가 있다. (N = 4)
2. N - 1, N번의 카드가 있다. 가장 뒤에 있는 카드를 가장 앞으로 옮긴다.(N회 반복)
   [3, 4] -> [4, 3] -> [3, 4] -> [4, 3]
3. [4, 3]의 카드 배열에 N - 2를 맨 앞에 추가한다. 가장 뒤에 있는 카드를 가장 앞으로 옮긴다.(N - 1회 반복)
   [2, 4, 3] -> [3, 2, 4] -> [4, 3, 2]
4. [4, 3, 2]의 카드 배열에 N - 3을 맨 앞에 추가한다. 가장 뒤에 있는 카드를 가장 앞으로 옮긴다.(N - 2회 반복)
   [1, 4, 3, 2] -> [2, 1, 4, 3]
5. 마지막으로 추가된 배열[2, 1, 4, 3]을 출력한다.

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

// N번 카드 추가
const arr = [N];

// N - 1부터 1까지 반복
for (let i = N - 1; i > 0; i--) {
  // i번째 값을 배열의 첫번째에 추가한다.
  arr.unshift(i);

  // i번 만큼 순회한다.
  for (let j = 0; j < i; j++) {
    // 마지막 카드를 추출한다.
    const lastCard = arr.pop();
    // 마지막 카드를 맨앞으로 옮긴다.
    arr.unshift(lastCard);
  }
}

console.log(arr.join(" "));

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

 

1590번: 캠프가는 영식

예제 1의 경우 150분, 200분, 250분, ..., 600분에 한 대씩 버스가 출발한다. 따라서 영식이는 300분에 버스를 타면 된다.

www.acmicpc.net

문제

영식이는 민식이와 함게 고속버스를 타고 캠프를 가야 하지만, 민식이는 영식이를 깨우지 않고 혼자 버스를 타고 캠프에 가버렸다.

영식이는 혼자 고속버스터미널까지 가서 캠프에 오려고 한다. 터미널에는 캠프 장소까지 운행하는 N가지의 버스가 있다. 각각의 버스는 시작 시각, 간격, 대수의 정보를 가지고 있다. 예를 들어, 어떤 버스의 시작 시각이 특점 시점을 기준으로 10분 후이고, 간격은 10분이고, 대수가 5대이면, 이 버스는 10분, 20분, 30분, 40분, 50분에 한 대씩 출발한다.

영식이는 버스터미널에 T분에 도착했다. 영식이가 버스를 타려면 최소 몇 분을 더 기다려야 하는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 버스의 개수 N과 영식이가 버스터미널에 도착하는 시간 T가 주어진다. 둘째 줄부터 총 N개의 줄에 각 버스의 시작 시각 Si, 간격 Ii, 대수 Ci가 공백을 사이에 두고 주어진다.

출력

첫째 줄에 영식이가 기다려야 하는 시간을 출력한다. 영식이가 도착하는 동시에 버스가 출발하면 정답은 0이다. 만약 버스가 없어서 캠프에 갈 수 없으면 -1을 출력한다. 정답은 231보다 작다.

제한

  • 1 ≤ N ≤ 50
  • 1 ≤ T ≤ 1,000,000
  • 1 ≤ Si ≤ 1,000,000
  • 1 ≤ Ii ≤ 10,000
  • 1 ≤ Ci ≤ 100

예제 입력 1 복사

1 285
150 50 10

예제 출력 1 복사

15

예제 입력 2 복사

1 123456
123456 10000 1

예제 출력 2 복사

0

예제 입력 3 복사

3 1
270758 196 67
904526 8930 66
121164 3160 56

예제 출력 3 복사

121163

예제 입력 4 복사

3 1000000
718571 2557 74
480573 9706 54
16511 6660 90

예제 출력 4 복사

-1

 

문제풀이(1)

버스의 개수 N, 영식이가 버스터미널에 도착하는 시간 T
버스의 시작 시각 S, 간격 I, 대수 C
대수 만큼 반복순회를 하며 버스의 시작 시각 + 간격 * 반복횟수(j)를 하면 버스의 간격별 버스의 시간을 알 수 있다.
버스의 간격별 시간이 영식이가 버스터미널에 도착하는 시간인 T 보다 크거나 같다면 반복순회를 종료한다.
영식이가 버스터미널에 도착하는 시간과 마지막 버스의 간격별 시간중 작은 값을 찾는다.
가장 작은 값을 찾았다면 가장 작은 값 - 영식이가 버스터미널에 도착하는 시간을 계산하면 기다려야하는 시간이 나온다.

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

const [N, T] = input.shift().split(" ").map(Number);
let answer = Infinity;

input.forEach((line) => {
  const [S, I, C] = line.split(" ").map(Number);

  const busDispatches = Array.from({ length: C }, (_, i) => S + I * i);
  const validDispatches = busDispatches.filter((busDispatch) => busDispatch >= T);

  if (validDispatches.length) answer = Math.min(answer, ...validDispatches);
});

console.log(answer !== Infinity ? answer - T : -1);

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

 

14381번: 숫자세는 양 (Small)

예제 입출력 1번에 대해서, 2 × 0 = 0, 3 × 0 = 0 등등으로 이어지므로, 블리트릭스는 0외에는 다른 숫자를 기록할 수 없을 것이며, 따라서 영원히 잠에 들 수 없다. 예제 입출력 2번의 경우, 1, 2, 3, 4,

www.acmicpc.net

문제

블리트릭스라는 양은 더 빨리 잠을 들기 위한 전략을 세웠다.

먼저, 숫자 N을 뽑는다. 그리고 N, 2 × N, 3 × N 등을 떠올린다. 숫자를 떠올릴 때 마다, 그 숫자의 모든 자리수의 숫자들을 적어놓는데, 이미 적은 숫자는 또 적지 않는다. 0에서 9까지의 모든 숫자가 적히게 되면 잠이 든다.

블리트릭스는 N에서 시작해서 i × N 후에는 (i + 1) × N을 떠올리게 된다. 예를 들어 N = 1692 일 경우, 다음 과 같이 진행된다:

  • N = 1692. 1, 2, 6, 9가 기록된다.
  • 2N = 3384. 1, 2, 3, 4, 6, 8, 9가 기록된다.
  • 3N = 5076. 모든 수가 기록되고, 잠에 빠진다.

블리트릭스가 잠에 빠지는 수는 무엇인가? 영원히 잠에 들 수 없다면 INSOMNIA라고 출력하라.

입력

첫 번째 행은 케이스의 개수, T이다. 다음 행부터는 T개의 케이스들이 나온다. 각 케이스는 블리트릭스가 고른 하나의 숫자 N으로 구성된다.

제한

  • 1 ≤ T ≤ 100.
  • 0 ≤ N ≤ 200.

출력

각 케이스에 대해서, 케이스 번호가 x이고 y가 정답일 때, Case #x: y라고 출력해야 한다.

예제 입력 1 복사

4
0
1
2
11

예제 출력 1 복사

Case #1: INSOMNIA
Case #2: 10
Case #3: 90
Case #4: 110

 

문제풀이(1)

입력 받은 N을 한자리씩 나눠서 set에 저장하며 1회씩 카운트한다.
0 ~ 9까지 모든 숫자를 set에 저장하고, set의 size가 10이 된다면
마지막에 완료되는 수를 출력하고, 만일 영원히 될 수 없는 수라면 'INSOMNIA'을 출력한다.

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

const check = (N) => {
  const digitsSet = new Set();

  for (let i = 1; i <= 200; i++) {
    let current = i * N;
    String(current)
      .split("")
      .forEach((digit) => digitsSet.add(digit));

    if (digitsSet.size === 10) return current;
  }

  return "INSOMNIA";
};

numbers.forEach((N, index) => {
  console.log(`Case #${index + 1}: ${check(N)}`);
});

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

 

29700번: 우당탕탕 영화예매

첫째 줄에 영화관 세로줄의 개수 $N$($ 1 \leq N \leq 1\,000$)과 가로줄의 개수 $M$($ 1 \leq M \leq 5\,000$), 영화를 관람할 동아리원의 수 $K$($ 1 \leq K \leq 10$)가 주어진다. 둘째 줄부터 $N$ 개의 줄에 걸쳐 그중

www.acmicpc.net

문제

도은이는 동아리 문화의 날을 맞이하여 동아리원들과 함께 좌석이 열의 직사각형 모양으로 배치되어 있는 영화관에서 영화를 보기로 했다. 도은이는 동아리원의 유대감을 중요하게 생각하기 때문에 이미 예매가 완료된 좌석을 피해 동아리원들이 모두 가로로 이어서 앉을 수 있도록 자리를 예매하고 싶어 한다. 도은이를 도와 모든 동아리원들이 가로로 이어서 앉을 수 있도록 예매하는 경우의 수는 총 몇 가지가 있을지 구해보자. 단, 예매한 좌석은 동일하지만, 각 사람이 앉는 위치만 바뀌는 경우는 한 가지로 본다.

입력

첫째 줄에 영화관 세로줄의 개수 (1≤N≤1000)과 가로줄의 개수 (1≤M≤5000), 영화를 관람할 동아리원의 수 (1≤K≤10)가 주어진다.

둘째 줄부터  개의 줄에 걸쳐 그중 번째 줄에는 번째 열의 좌석 예매 현황이 길이 인 문자열 s로 주어진다. 번째 문자는 번째 좌석의 예매 현황을 나타내는데, 이 문자가 ''이라면 예매 가능한 빈 좌석을, 이 문자가 ''이라면 예매가 완료되어 예매가 불가능한 좌석을 나타낸다.

출력

동아리원들이 모두 가로로 이어서 앉을 수 있도록 영화를 예매하는 경우의 수를 출력한다. 단, 문제에서 주어진 조건에 맞게 영화를 예매할 수 있는 방법이 없다면 0을 출력한다.

예제 입력 1 복사

3 5 3
11000
01010
10000

예제 출력 1 복사

3

예제 입력 2 복사

3 4 3
1101
1001
0101

예제 출력 2 복사

0

 

문제풀이(1)

N x M의 영화관 자리에서 이미 완료가 된 자리를 제외한 빈자리를 동아리원들이 가로로 연속되게 앉는 방법의 개수를 구하는 문제이다.

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

const [N, M, K] = input.shift().split(" ").map(Number);

let answer = 0;

for (let i = 0; i < N; i++) {
  for (let j = 0; j <= M - K; j++) {
    const seatList = input[i].slice(j, K + j).split("");

    if (seatList.filter((el) => el === "0").length === K) {
      answer++;
    }
  }
}

console.log(answer);

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

 

20363번: 당근 키우기

첫째 줄에 X와 Y (0 ≤ X, Y ≤ 109)를 의미하는 정수가 공백으로 구분되어 주어진다.

www.acmicpc.net

문제

꽉꽉나라의 농부 오리는 당근을 키우려고 한다. 꽉꽉나라에서는 씨앗이 X만큼의 온기와 Y만큼의 수분을 가지면 당근으로 자란다고 한다.

씨앗은 햇빛을 1번 받을 때마다 1만큼의 온기가 증가하고, 햇빛을 10번 받을 때마다 1만큼의 수분이 감소한다.

씨앗은 물을 1번 받을 때마다 1만큼의 수분이 증가하고, 물을 10번 받을 때마다 1만큼의 온기가 감소한다.

만약, 감소되어야 하는 온기 혹은 수분이 이미 0이라면 감소되지 않는다. 즉, 온기와 수분은 음수가 되지 않는다. 맨 처음 씨앗의 온기와 수분은 0이다.

오리는 당근을 효율적으로 키우기 위해, 당근이 자랄 때까지 햇빛과 물을 주는 횟수의 합을 최소화하려고 한다. 예를 들어, X = 10, Y = 10이라고 하자.

씨앗에 햇빛을 10번 주면 온기 10, 수분 0이 된다. 그리고, 물을 10번 주면 온기 9. 수분 10이 된다. 마지막으로 햇빛을 1번 주면 온기 10, 수분 10으로 당근이 자라게 된다. 이때, 햇빛과 물을 준 횟수의 합은 21이고 위 예제에서의 최솟값이다.

X와 Y가 주어졌을 때, 당근이 자랄 때까지 햇빛과 물을 주는 횟수의 합의 최솟값을 구하는 프로그램을 작성하라.

입력

첫째 줄에 X와 Y (0 ≤ X, Y ≤ 109)를 의미하는 정수가 공백으로 구분되어 주어진다.

출력

당근이 자랄 때까지 햇빛과 물을 주는 횟수의 합의 최솟값을 나타내는 정수를 출력하라.

예제 입력 1 복사

10 10

예제 출력 1 복사

21

예제 입력 2 복사

123456 12345

예제 출력 2 복사

137035

 

문제풀이(1)
햇빛을 10번 받을 때 마다 수분이 1 감소하고, 물을 10번 줄 때 마다 온기가 1 감소한다.
맨 처음 온기와 수분은 0이다.
X와 Y의 값을 더해주고 10마다 온기 또는 수분이 감소하기 떄문에 최소한으로 하려면 X와 Y의 최솟값을 10으로 나눈 것을 합해준다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const [X, Y] = require("fs").readFileSync(filePath).toString().trim().split(" ").map(Number);

console.log(X + Y + Math.floor(Math.min(X, Y) / 10));

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

 

12927번: 배수 스위치

첫째 줄에 전구의 상태가 1번 전구부터 차례대로 주어진다. Y는 전구가 켜 있는 경우, N은 전구가 꺼져있는 경우이다. 전구의 개수는 1보다 크거나 같고 1,000보다 작거나 같은 자연수이다.

www.acmicpc.net

문제

강호는 전구 N개를 가지고 있다. 전구는 1번부터 N번까지 번호가 매겨져 있으며, 일렬로 놓여져 있다. 전구는 켜져있거나 꺼져있다.

강호는 모든 전구를 끄려고 한다. 강호는 전구를 켜고 끌 수 있는 스위치 N개를 가지고 있고, 스위치도 1번부터 N번까지 번호가 매겨져 있다. i번 스위치는 i의 배수 번호를 가지는 전구의 상태를 모두 반전시킨다.

현재 전구의 상태가 주어졌을 때, 모든 전구를 끄기 위해서 스위치를 몇 번 눌러야하는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 전구의 상태가 1번 전구부터 차례대로 주어진다. Y는 전구가 켜 있는 경우, N은 전구가 꺼져있는 경우이다. 전구의 개수는 1보다 크거나 같고 1,000보다 작거나 같은 자연수이다.

출력

모든 전구를 끄기 위해서 스위치를 몇 번 눌러야 하는지 출력한다. 만약, 모든 전구를 끌 수 없다면 -1을 출력한다.

예제 입력 1 복사

YYYYYY

예제 출력 1 복사

1

예제 입력 2 복사

YNYNYNYNY

예제 출력 2 복사

2

예제 입력 3 복사

NNNNNNNNNN

예제 출력 3 복사

0

예제 입력 4 복사

YYYNYYYNYYYNYYNYYYYN

예제 출력 4 복사

4

 

문제풀이(1)

원래는 에라토스테네스의 체를 생각했지만 i번째 이전의 값들은 수정하지 않는다는 것을 다시 깨닫고 풀었다.

1. i번째의 배수마다 전등의 동작 유무를 반전시키며 카운트를 해준다.
2. 모든 스위치가 꺼졌을 때의 카운트를 출력한다.

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

let count = 0;

for (let i = 0; i < arr.length; i++) {
  if (arr[i] === "Y") {
    arr[i] = "N";
    count++;

    for (let j = i + 1; j <= arr.length; j += i + 1) {
      arr[j - 1] = arr[j - 1] === "Y" ? "N" : "Y";
    }
  }
}

console.log(count);

 

 

+ Recent posts