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

 

9507번: Generations of Tribbles

꿍은 군대에서 진짜 할짓이 없다. 그래서 꿍만의 피보나치를 만들어보려고 한다. 기존의 피보나치는 너무 단순해서 꿍은 좀더 복잡한 피보나치를 만들어보고자 한다. 그래서 다음과 같은 피보

www.acmicpc.net

문제

꿍은 군대에서 진짜 할짓이 없다. 그래서 꿍만의 피보나치를 만들어보려고 한다. 기존의 피보나치는 너무 단순해서 꿍은 좀더 복잡한 피보나치를 만들어보고자 한다. 그래서 다음과 같은 피보나치를 만들었다. 꿍만의 피보나치 함수가 koong(n)이라고 할 때,

n < 2 :                         1
n = 2 :                         2
n = 3 :                         4
n > 3 : koong(n − 1) + koong(n − 2) + koong(n − 3) + koong(n − 4)

이다.

여러분도 꿍 피보나치를 구해보아라.

입력

입력의 첫 번째 줄을 테스트 케이스의 개수 t (0 < t < 69)가 주어진다. 다음 t줄에는 몇 번째 피보나치를 구해야하는지를 나타내는 n(0 ≤ n ≤ 67)이 주어진다.

출력

각 테스트 케이스에 대해, 각 줄에 꿍 피보나치값을 출력하라.

예제 입력 1 복사

8
0
1
2
3
4
5
30
67

예제 출력 1 복사

1
1
2
4
8
15
201061985
7057305768232953720

 

문제풀이(1)

변형된 피보나치수를 구하면되는 문제이다.
koong(n − 1) + koong(n − 2) + koong(n − 3) + koong(n − 4)
기본적으로 주어지는 수는 1, 1, 2, 4이다.

주어지는 수의 범위가 int를 넘어가기 때문에 Bigint를 사용한다.

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

const N = input.shift();
const answer = [];

for (let i = 0; i < N; i++) {
  const dp = [1, 1, 2, 4];

  for (let j = 4; j < input[i] + 1; j++) {
    const num = BigInt(dp[j - 1]) + BigInt(dp[j - 2]) + BigInt(dp[j - 3]) + BigInt(dp[j - 4]);
    dp.push(num.toString());
  }
  answer.push(dp[input[i]]);
}

console.log(answer.join("\n"));

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

 

25192번: 인사성 밝은 곰곰이

첫번째 새로운 사람이 들어온 뒤  pjshwa, chansol, chogahui05은 모두 곰곰티콘으로 인사했다. 두번째 새로운 사람이 들어온 뒤  pjshwa와 chansol은 다시 곰곰티콘으로 인사했다.

www.acmicpc.net

문제

알고리즘 입문방 오픈 채팅방에서는 새로운 분들이 입장을 할 때마다 곰곰티콘을 사용해 인사를 한다. 이를 본 문자열 킬러 임스는 채팅방의 기록을 수집해 그 중 곰곰티콘이 사용된 횟수를 구해 보기로 했다.

ENTER는 새로운 사람이 채팅방에 입장했음을 나타낸다. 그 외는 채팅을 입력한 유저의 닉네임을 나타낸다. 닉네임은 숫자 또는 영문 대소문자로 구성되어 있다.

새로운 사람이 입장한 이후 처음 채팅을 입력하는 사람은 반드시 곰곰티콘으로 인사를 한다. 그 외의 기록은 곰곰티콘을 쓰지 않은 평범한 채팅 기록이다.

채팅 기록 중 곰곰티콘이 사용된 횟수를 구해보자!

입력

첫 번째 줄에는 채팅방의 기록 수를 나타내는 정수  이 주어진다. (1≤N≤100000)

두 번째 줄부터  개의 줄에 걸쳐 새로운 사람의 입장을 나타내는 ENTER, 혹은 채팅을 입력한 유저의 닉네임이 문자열로 주어진다. (문자열길이1≤문자열 길이≤20)

첫 번째 주어지는 문자열은 무조건 ENTER이다.

출력

채팅 기록 중 곰곰티콘이 사용된 횟수를 출력하시오.

예제 입력 1 복사

9
ENTER
pjshwa
chansol
chogahui05
lms0806
pichulia
r4pidstart
swoon
tony9402

예제 출력 1 복사

8

 

문제풀이(1)

ENTER : 새로운 사람이 채팅방에 입장했음.
그 외 : 채팅을 입력한 유저의 닉네임
ENTER로 새로운 사람이 채팅방에 입장했다는 커맨드 다음으로 나온 닉네임의 개수를 구한다.
ENTER는 여러번 나올수 있고, 한 번의 ENTER에는 중복된 닉네임이 없어야하며 다른 ENTER에는 이전 ENTER와 중복된 닉네임이 있을 수 있다.
set을 이용해서 중복제거를 하고 ENTER가 나올때마다 set을 초기화 해주면 된다.

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

const N = Number(input.shift());

const set = new Set();
let answer = 0;

for (let i = 0; i < N; i++) {
  if (input[i] === "ENTER") {
    answer += set.size;
    set.clear();
    continue;
  }

  set.add(input[i]);
  if (i === N - 1) {
    answer += set.size;
  }
}

console.log(answer);

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

 

4134번: 다음 소수

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다.

www.acmicpc.net

문제

정수 n(0 ≤ n ≤ 4*109)가 주어졌을 때, n보다 크거나 같은 소수 중 가장 작은 소수 찾는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다.

출력

각각의 테스트 케이스에 대해서 n보다 크거나 같은 소수 중 가장 작은 소수를 한 줄에 하나씩 출력한다.

예제 입력 1 복사

3
6
20
100

예제 출력 1 복사

7
23
101

 

문제풀이(1)

주어진 수의 다음 소수를 구하는 문제이다.
소수는 1과 자기 자신만을 약수로 가지는 수이다. 1은 소수가 아니다.
소수 판별 함수를 구현한다음 주어진 수의 다음 수 부터 소수인지 판별하여 소수일 경우 출력하면 된다.

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

const answer = [];

const isPrime = (number) => {
  if (number < 2) return false;

  for (let i = 2; i <= Math.sqrt(number); i++) {
    if (number % i === 0) {
      return false;
    }
  }

  return true;
};

for (let i = 0; i < T; i++) {
  let number = arr[i];
  while (true) {
    if (isPrime(number)) {
      break;
    } else {
      number++;
    }
  }

  answer.push(number);
}

console.log(answer.join("\n"));

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

 

1969번: DNA

DNA란 어떤 유전물질을 구성하는 분자이다. 이 DNA는 서로 다른 4가지의 뉴클레오티드로 이루어져 있다(Adenine, Thymine, Guanine, Cytosine). 우리는 어떤 DNA의 물질을 표현할 때, 이 DNA를 이루는 뉴클레오

www.acmicpc.net

문제

DNA란 어떤 유전물질을 구성하는 분자이다. 이 DNA는 서로 다른 4가지의 뉴클레오티드로 이루어져 있다(Adenine, Thymine, Guanine, Cytosine). 우리는 어떤 DNA의 물질을 표현할 때, 이 DNA를 이루는 뉴클레오티드의 첫글자를 따서 표현한다. 만약에 Thymine-Adenine-Adenine-Cytosine-Thymine-Guanine-Cytosine-Cytosine-Guanine-Adenine-Thymine로 이루어진 DNA가 있다고 하면, “TAACTGCCGAT”로 표현할 수 있다. 그리고 Hamming Distance란 길이가 같은 두 DNA가 있을 때, 각 위치의 뉴클오티드 문자가 다른 것의 개수이다. 만약에 “AGCAT"와 ”GGAAT"는 첫 번째 글자와 세 번째 글자가 다르므로 Hamming Distance는 2이다.

우리가 할 일은 다음과 같다. N개의 길이 M인 DNA s1, s2, ..., sn가 주어져 있을 때 Hamming Distance의 합이 가장 작은 DNA s를 구하는 것이다. 즉, s와 s1의 Hamming Distance + s와 s2의 Hamming Distance + s와 s3의 Hamming Distance ... 의 합이 최소가 된다는 의미이다.

입력

첫 줄에 DNA의 수 N과 문자열의 길이 M이 주어진다. 그리고 둘째 줄부터 N+1번째 줄까지 N개의 DNA가 주어진다. N은 1,000보다 작거나 같은 자연수이고, M은 50보다 작거나 같은 자연수이다.

출력

첫째 줄에 Hamming Distance의 합이 가장 작은 DNA 를 출력하고, 둘째 줄에는 그 Hamming Distance의 합을 출력하시오. 그러한 DNA가 여러 개 있을 때에는 사전순으로 가장 앞서는 것을 출력한다.

예제 입력 1 복사

5 8
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT

예제 출력 1 복사

TAAGATAC
7

예제 입력 2 복사

4 10
ACGTACGTAC
CCGTACGTAG
GCGTACGTAT
TCGTACGTAA

예제 출력 2 복사

ACGTACGTAA
6

 

문제풀이(1)

Hamming Distance의 합이 가장 작은 DNA는 각 자리수별 가장 많이 등장한 DNA며,
Hamming Distance의 합은 가장 작은 DNA를 나열한 것에서 각 자리수마다 다른 것을 더한 값이다.
1. 각 자리수별 가장 많이 등장한 DNA를 찾는다.
2. 각 자리수별 Hamming Distance의 합을 구한다.

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

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

let hammingDistanceDNA = "";
let countHammingDistanceDNA = 0;

for (let i = 0; i < M; i++) {
  const map = new Map();
  for (let j = 0; j < N; j++) {
    const dna = input[j][i];
    map.has(dna) ? map.set(dna, map.get(dna) + 1) : map.set(dna, 1);
  }
  const hamming = [...map].sort().reduce((a, b) => (a[1] >= b[1] ? a : b));
  hammingDistanceDNA += hamming[0];
  countHammingDistanceDNA += N - hamming[1];
}

console.log(hammingDistanceDNA);
console.log(countHammingDistanceDNA);

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

 

28278번: 스택 2

첫째 줄에 명령의 수 N이 주어진다. (1 ≤ N ≤ 1,000,000) 둘째 줄부터 N개 줄에 명령이 하나씩 주어진다. 출력을 요구하는 명령은 하나 이상 주어진다.

www.acmicpc.net

문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

  1. 1 X: 정수 X를 스택에 넣는다. (1 ≤ X ≤ 100,000)
  2. 2: 스택에 정수가 있다면 맨 위의 정수를 빼고 출력한다. 없다면 -1을 대신 출력한다.
  3. 3: 스택에 들어있는 정수의 개수를 출력한다.
  4. 4: 스택이 비어있으면 1, 아니면 0을 출력한다.
  5. 5: 스택에 정수가 있다면 맨 위의 정수를 출력한다. 없다면 -1을 대신 출력한다.

입력

첫째 줄에 명령의 수 N이 주어진다. (1 ≤ N ≤ 1,000,000)

둘째 줄부터 N개 줄에 명령이 하나씩 주어진다.

출력을 요구하는 명령은 하나 이상 주어진다.

출력

출력을 요구하는 명령이 주어질 때마다 명령의 결과를 한 줄에 하나씩 출력한다.

예제 입력 1 복사

9
4
1 3
1 5
3
2
5
2
2
5

예제 출력 1 복사

1
2
5
3
3
-1
-1

 

문제풀이(1)

1. 1 X: 정수 X를 스택에 넣는다. (1 ≤ X ≤ 100,000)
2. 2: 스택에 정수가 있다면 맨 위의 정수를 빼고 출력한다. 없다면 -1을 대신 출력한다.
3. 3: 스택에 들어있는 정수의 개수를 출력한다.
4. 4: 스택이 비어있으면 1, 아니면 0을 출력한다.
5. 5: 스택에 정수가 있다면 맨 위의 정수를 출력한다. 없다면 -1을 대신 출력한다.
위의 조건에 맞게 스택을 구현하면 된다.

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

class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class Stack {
  constructor(value) {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }

  push(value) {
    const node = new Node(value);

    if (!this.head) {
      this.head = node;
    } else {
      node.prev = this.tail;
      this.tail.next = node;
    }

    this.tail = node;
    this.size++;
  }

  pop() {
    if (this.size === 0) {
      return -1;
    }

    const value = this.tail.value;

    if (this.head === this.tail) {
      this.head = null;
      this.tail = null;
    } else {
      this.tail = this.tail.prev;
      this.tail.next = null;
    }

    this.size--;

    return value;
  }

  getSize() {
    return this.size;
  }

  empty() {
    return this.size ? 0 : 1;
  }

  getTop() {
    return this.tail ? this.tail.value : -1;
  }
}

const stack = new Stack();

let answer = "";

for (let i = 0; i < Number(N); i++) {
  const [command, value] = arr[i].split(" ");

  switch (command) {
    case "1":
      stack.push(value);
      break;
    case "2":
      answer += `${stack.pop()}\n`;
      break;
    case "3":
      answer += `${stack.getSize()}\n`;
      break;
    case "4":
      answer += `${stack.empty()}\n`;
      break;
    case "5":
      answer += `${stack.getTop()}\n`;
      break;
  }
}

console.log(answer.trim());

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

 

2491번: 수열

0에서부터 9까지의 숫자로 이루어진 N개의 숫자가 나열된 수열이 있다. 그 수열 안에서 연속해서 커지거나(같은 것 포함), 혹은 연속해서 작아지는(같은 것 포함) 수열 중 가장 길이가 긴 것을 찾

www.acmicpc.net

문제

0에서부터 9까지의 숫자로 이루어진 N개의 숫자가 나열된 수열이 있다. 그 수열 안에서 연속해서 커지거나(같은 것 포함), 혹은 연속해서 작아지는(같은 것 포함) 수열 중 가장 길이가 긴 것을 찾아내어 그 길이를 출력하는 프로그램을 작성하라. 

예를 들어 수열 1, 2, 2, 4, 4, 5, 7, 7, 2 의 경우에는 1 ≤ 2 ≤ 2 ≤ 4 ≤ 4 ≤ 5 ≤ 7 ≤ 7 이 가장 긴 구간이 되므로 그 길이 8을 출력한다. 수열 4, 1, 3, 3, 2, 2, 9, 2, 3 의 경우에는 3 ≥ 3 ≥ 2 ≥ 2 가 가장 긴 구간이 되므로 그 길이 4를 출력한다. 또 1, 5, 3, 6, 4, 7, 1, 3, 2, 9, 5 의 경우에는 연속해서 커지거나 작아지는 수열의 길이가 3 이상인 경우가 없으므로 2를 출력하여야 한다.

입력

첫째 줄에는 수열의 길이 N이 주어지고, 둘째 줄에는 N개의 숫자가 빈칸을 사이에 두고 주어진다. N은 1 이상 100,000 이하의 정수이다.

출력

첫째 줄에 가장 긴 길이를 출력한다.

예제 입력 1 복사

9
1 2 2 4 4 5 7 7 2

예제 출력 1 복사

8

예제 입력 2 복사

9
4 1 3 3 2 2 9 2 3

예제 출력 2 복사

4

 

문제풀이(1)

연속해서 커지거나 작아지는 수열이 가장 큰 길이를 구하면된다.
연속해서 커지는지 확인하는 로직, 연속해서 작아지는지 확인하는 로직 2개가 필요하다.
같은 숫자 예를들어 2 -> 2는 연속해서 작아지거나 커지는 것으로 간주한다.

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

const sequence = arr[0].split(" ").map(Number);

let upCount = 1;
let downCount = 1;

const answer = [];

for (let i = 0; i < Number(N); i++) {
  const nowNum = sequence[i];
  const nextNum = sequence[i + 1];

  if (nowNum <= nextNum) {
    upCount++;
  } else if (nowNum > nextNum) {
    upCount = 1;
  }

  if (nowNum >= nextNum) {
    downCount++;
  } else if (nowNum < nextNum) {
    downCount = 1;
  }
  answer.push(upCount);
  answer.push(downCount);
}

console.log(Math.max(...answer));

 

문제풀이(2)

1. 배열에 모든 count를 넣는 것이 아니라 바로 비교하여 메모리 최적화
2. 최고 값을 찾는 max 메서드를 사용하지 않음으로 실행시간 최적화
메모리 - 20132kb -> 12192kb
실행시간 - 208ms -> 188ms

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

const sequence = arr[0].split(" ").map(Number);

let upCount = 1;
let upResult = 1;

let downCount = 1;
let downResult = 1;

for (let i = 0; i < Number(N); i++) {
  const nowNum = sequence[i];
  const nextNum = sequence[i + 1];

  if (nowNum <= nextNum) {
    upCount++;
    if (upCount >= upResult) {
      upResult = upCount;
    }
  } else if (nowNum > nextNum) {
    upCount = 1;
  }

  if (nowNum >= nextNum) {
    downCount++;
    if (downCount >= downResult) {
      downResult = downCount;
    }
  } else if (nowNum < nextNum) {
    downCount = 1;
  }
}

console.log(upResult >= downResult ? upResult : downResult);

+ Recent posts