https://www.acmicpc.net/problem/1759
1759번: 암호 만들기
첫째 줄에 두 정수 L, C가 주어진다. (3 ≤ L ≤ C ≤ 15) 다음 줄에는 C개의 문자들이 공백으로 구분되어 주어진다. 주어지는 문자들은 알파벳 소문자이며, 중복되는 것은 없다.
www.acmicpc.net
C개의 문자 중 L개를 고른 결과를 사전순으로 정렬하여 모두 출력하는 문제이므로, 백트래킹을 이용해 문자열의 길이와 사용된 문자 중 가장 큰 문자를 추적해 가며 출력하는 문제이다.
#include <cstdio>
#define MAX_C 15
// chr[i]: 알파벳 i가 후보로 주어졌다면 true, 아니라면 false
bool chr[26];
// 출력할 문자열을 저장할 컨테이너
char str[MAX_C];
// L: 만들 암호의 길이, C: 암호 후보 문자의 수
short L, C;
// 길이가 len이고 마지막으로 알파벳 last를 사용한 암호를 만든 뒤
// 나머지 암호를 완성시킨다
void backtrack(int len, int last) {
// 암호를 전부 완성시키지 못했다면
if (len < L) {
// 아직 쓰지 않은 문자열이 있을 때
for (int i = last + 1; i < 26; i++) if (chr[i]) {
// 각 문자를 암호의 끝에 붙인 뒤 해당 과정을 다시 시행한다
str[len] = i + 'a';
backtrack(len + 1, i);
}
}
// 암호 후보가 완성되었다면
else {
// a: 모음 수, b: 자음 수
int a = 0, b = 0;
// 모음의 수와 자음의 수를 센다
for (int i = 0; i < L; i++) switch (str[i]) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u': a++; break;
default: b++;
}
// 모음 수 혹은 자음 수가 부족하다면 함수를 종료한다
if ((a < 1) || (b < 2)) return;
// 암호 후보를 출력한다
for (int i = 0; i < L; i++) printf("%c", str[i]);
printf("\n");
}
}
int main() {
// 입력에 사용할 버퍼
char buf;
// 암호의 길이와 후보 문자의 수, 각 후보 문자를 입력받는다
scanf("%hd %hd", &L, &C);
for (int i = 0; i < C; i++) {
scanf("%*c%c", &buf);
chr[buf - 'a'] = true;
}
// 백트래킹을 이용해 암호 해독을 시작한다
backtrack(0, -1);
return 0;
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
1780번: 종이의 개수 (0) | 2021.12.09 |
---|---|
1764번: 듣보잡 (0) | 2021.12.09 |
1753번: 최단경로 (0) | 2021.12.09 |
1712번: 손익분기점 (0) | 2021.12.09 |
1697번: 숨바꼭질 (0) | 2021.12.09 |