알고리즘 풀이

[백준 1759, NodeJS] 암호만들기

FE코크 2021. 1. 19. 13:00

www.acmicpc.net/problem/1759

 

1759번: 암호 만들기

첫째 줄에 두 정수 L, C가 주어진다. (3 ≤ L ≤ C ≤ 15) 다음 줄에는 C개의 문자들이 공백으로 구분되어 주어진다. 주어지는 문자들은 알파벳 소문자이며, 중복되는 것은 없다.

www.acmicpc.net

백준 1759번 암호 만들기 풀이입니다.

저는 브루트포스 알고리즘, 순열로 풀었습니다.

바로 어제 최백준 조교가 방 열쇠를 주머니에 넣은 채 깜빡하고 서울로 가 버리는 황당한 상황에 직면한 조교들은, 702호에 새로운 보안 시스템을 설치하기로 하였다. 이 보안 시스템은 열쇠가 아닌 암호로 동작하게 되어 있는 시스템이다.
암호는 서로 다른 L개의 알파벳 소문자들로 구성되며 최소 한 개의 모음(a, e, i, o, u)과 최소 두 개의 자음으로 구성되어 있다고 알려져 있다. 또한 정렬된 문자열을 선호하는 조교들의 성향으로 미루어 보아 암호를 이루는 알파벳이 암호에서 증가하는 순서로 배열되었을 것이라고 추측된다. 즉, abc는 가능성이 있는 암호이지만 bac는 그렇지 않다.
새 보안 시스템에서 조교들이 암호로 사용했을 법한 문자의 종류는 C가지가 있다고 한다. 이 알파벳을 입수한 민식, 영식 형제는 조교들의 방에 침투하기 위해 암호를 추측해 보려고 한다. C개의 문자들이 모두 주어졌을 때, 가능성 있는 암호들을 모두 구하는 프로그램을 작성하시오.

문제를 보고 정리하면

  1. 암호들은 L개의 알파벳 소문자들로 구성된다.
  2. 암호들은 최소 한 개의 모음(a,e,i,o,u)를 포함시킨다.
  3. 암호들은 최소 두개의 자음을 포함시킨다.
  4. 암호들은 알파벳이 증가하는 순서를 가진다(abc 가능, bac불가능)
  5. 가능성 있는 암호들을 모두 출력하는 프로그램을 구한다.

우선 입력 받은 값을 선언하고 sort 메서드로 알파벳을 증가하는 순서로 정렬 시킨다.(1번, 4번)

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

const inputCondition = input[0].split(" ").map((str) => Number(str));
const L = inputCondition[0];
const C = inputCondition[1];
const inputAlphabet = input[1]
  .split(" ")
  .sort((a, b) => a.charCodeAt() - b.charCodeAt());
const vowel = ["a", "e", "i", "o", "u"];

 

최소 한 개의 모음최소 두개의 자음을 포함 하는지에 대한 판별하는 함수를 만든다.(2번, 3번)

const isVaild = (m) => {
  if (
    m.filter((n) => vowel.includes(n)).length > 0 &&
    m.filter((n) => !vowel.includes(n)).length > 1
  ) {
    return true;
  }
  return false;
};

 

브루트포스 알고리즘, 순열로 가능성 있는 모든 암호를 구한다.

const getPassword = (inputAlphabet, L) => {
  const maxLength = L;
  const inputArr = inputAlphabet.slice();
  let result = ``;

  const permutation = (arr, m = [], i = 0) => {
    if (m.length === maxLength) {
      if (isVaild(m)) {
        result += m.join("") + `\n`;
      }
    } else {
      for (i; i < arr.length; i++) {
        let curr = arr.slice();
        let next = curr.splice(i, 1);
        permutation(curr.slice(), m.concat(next), i);
      }
    }
  };
  permutation(inputArr);

  return console.log(result);
};

getPassword(inputAlphabet, L);

문제 제출

 

아무래도 모든 경우의 수를 다 검사하다 보니 오래 걸린다...

좀 더 빠른 방법을 찾아 봐야 겠다.

 

전체 소스 코드는 여기에 있습니다.

colorscripter.com/s/ctxLyyv

 

공유된 코드 - Color Scripter

저작권자 : kangit2013@gmail.com 삭제 요청 코드 설명 : 백준1759

colorscripter.com