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);

 

 

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

 

9575번: 행운의 수

각각의 테스트 케이스마다 입력으로 주어진 수열을 이용해 만들 수 있는 서로 다른 행운의 수의 개수를 한 줄에 하나씩 출력한다.

www.acmicpc.net

 

문제

한슬이는 5와 8이 행운의 수라고 생각한다. 그래서 한슬이는 각 자리가 5와 8로만 이뤄져 있는 수를 행운의 수라고 한다.

정수 수열 A, B, C가 주어졌을 때 세 수열에서 각각 하나의 정수를 골라서 만들 수 있는 서로 다른 행운의 수의 개수를 구해보자.

예를 들어 A = [1, 10, 100], B = [3, 53], C = [4, 54]라고 한다면, 행운의 수를 만드는 방법은 8 = 1 + 3 + 4, 58 = 1 + 3 + 54, 58 = 1 + 53 + 4와 같이 총 3가지가 있다. 58은 2가지 방법으로 만들 수 있으니, 서로 다른 행운의 수의 개수는 8과 58, 총 2개이다.

입력

첫째 줄에 테스트 케이스의 수가 주어진다.

각 테스트 케이스의 첫째 줄에 A의 크기 N이 주어지고, 둘째 줄에 수열 A의 원소가 주어진다. 수열 A의 원소는 공백으로 구분되어 있다.

다음 셋째 줄에는 B의 크기 M, 넷째 줄에는 수열 B의 원소, 다섯째 줄에는 C의 크기 K, 여섯째 줄에는 C의 원소가 주어지며, 수열 A의 정보와 같은 형식으로 되어 있다.

수열의 크기는 50을 넘지 않는 양의 정수이고, 수열의 원소는 30,000보다 작거나 같은 양의 정수이다.

출력

각각의 테스트 케이스마다 입력으로 주어진 수열을 이용해 만들 수 있는 서로 다른 행운의 수의 개수를 한 줄에 하나씩 출력한다.

예제 입력 1 복사

2
6
100 1 10 100 1 1
7
3 53 53 53 53 53 53
6
4 54 4 54 4 54
1
47
1
500
1
33

예제 출력 1 복사

2
0

 

문제풀이(1)

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

for (let i = 0; i < T; i++) {
  const testCaseArr = input.splice(0, 6);
  const A = testCaseArr[1].split(" ").map(Number);
  const B = testCaseArr[3].split(" ").map(Number);
  const C = testCaseArr[5].split(" ").map(Number);

  const luckySet = new Set();

  for (const a of A) {
    for (const b of B) {
      for (const c of C) {
        const sum = a + b + c;
        if (isLuckyNumber(sum)) {
          luckySet.add(sum);
        }
      }
    }
  }
  console.log(luckySet.size);
}

function isLuckyNumber(num) {
  const forbiddenDigits = ["0", "1", "2", "3", "4", "6", "7", "9"];
  const digits = num.toString().split("");
  return !digits.some((digit) => forbiddenDigits.includes(digit));
}

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

 

1544번: 사이클 단어

사이클 단어는 어떤 단어를 원형 모양으로 차례대로 쓴 것이다. 따라서, 어떤 단어를 이렇게 쓴 후에 임의의 단어를 고른다. 그 후에 시계방향으로 차례대로 읽으면 그 것이 단어가 된다. 만약에

www.acmicpc.net

문제

사이클 단어는 어떤 단어를 원형 모양으로 차례대로 쓴 것이다. 따라서, 어떤 단어를 이렇게 쓴 후에 임의의 단어를 고른다. 그 후에 시계방향으로 차례대로 읽으면 그 것이 단어가 된다. 만약에 단어 A와 단어 B가 있을 때, 단어 B를 원형으로 써서, 단어 A와 같이 읽을 수 있으면, 두 단어는 같은 단어이다. 따라서, picture와 turepic은 같은 단어다.

N개의 단어가 주어졌을 때, 서로 다른 단어가 총 몇 개인지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 단어의 개수 N이 주어진다. 둘째 줄부터 단어가 한 줄에 하나씩 주어진다. 단어는 영어 소문자로만 이루어져 있다. N은 50보다 작거나 같은 자연수이며, 단어의 길이는 최대 50이다.

출력

첫째 줄에 서로 다른 단어가 몇 개인지 출력한다.

예제 입력 1 복사

5
picture
turepic
icturep
word
ordw

예제 출력 1 복사

2

예제 입력 2 복사

7
ast
ats
tas
tsa
sat
sta
ttt

예제 출력 2 복사

3

 

문제풀이(1)

브루트포스 문제이다.
1. i번째 단어를 입력받으면 해당 단어로 만들 수 있는 모든 경우의 수를 만든다.
2. 이전에 만들어진 모든 회전들과 현재 문자열의 회전들을 비교하여, 현재 문자열이 새로운 회전을 만들었는지 확인한다.
3. 만약 현재 문자열이 새로운 회전을 만들었다면, 카운트를 증가시킨다.

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

const n = Number(input[0]);
const rotations = Array.from({ length: n }, () => []);

let count = 0;

for (let i = 0; i < n; i++) {
  const current = input[i + 1];

  const currentRotations = Array.from({ length: current.length }, (_, j) => current.slice(j) + current.slice(0, j));

  const isUnique = rotations
    .slice(0, i)
    .every((prevRotations) => !prevRotations.some((prev) => currentRotations.includes(prev)));

  if (isUnique) {
    count++;
  }

  rotations[i] = currentRotations;
}

console.log(count);

+ Recent posts