알고리즘
[BOJ] - 암호 만들기 / 1759번 (Java)
JinHxxxxKim
2024. 2. 21. 17:46
[BOJ] - 암호 만들기 / 1759번 (Java)
1. 문제 접근
C개의 문자들이 주어질 때, L개의 문자로 이루어진 암호 문자열을 만들면 된다.
이 때, 1개 이상의 모음, 2개 이상의 자음이 포함되어야하며, 암호문은 반드시 증가하는 순서로 배열되어있다는 것이다.
일반적인 조합(Combination)문제에 대해 약간의 추가적인 조건들이 추가된 문제라고 생각한다.
`암호문은 반드시 증가하는 순서로 배열`라는 조건을 이용하여 조합을 구성하기 전에 주어진 문자 배열을 오름차순으로 정렬해야한다.
또한 기저조건(`selectIdx == L`)을 만족할 경우, 추가적으로 L개의 문자열을 조회하며 모음, 자음의 개수가 조건을 만족하는지 여부를 확인해야한다.
2. 코드
package boj;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
/**
* [BOJ] - 암호 만들기 / 1759번
* @author JinHxxxxKim
*
* 1. 두 정수 L, C를 입력받는다.
* - L: 암호문의 길이
* - C: 주어진 알파벳의 수
* 2. C개의 문자들을 입력받는다.
* 3. 주어진 문자들을 오름차순으로 정렬한다.
* 4. 조합을 구성한다.
* - 기저조건: selectIdx == L
* - 자음, 모음의 수가 충족되지 않으면 append하지 않는다.
*/
public class Sol_1759 {
private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static StringBuilder sb = new StringBuilder();
private static StringTokenizer st;
private static int L, C;
private static char[] alphabet;
private static int[] select;
public static void main(String[] args) throws Exception {
st = new StringTokenizer(br.readLine().trim());
L = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
alphabet = new char[C];
st = new StringTokenizer(br.readLine().trim());
for (int idx = 0; idx < C; ++idx) {
alphabet[idx] = st.nextToken().charAt(0);
}
Arrays.sort(alphabet);
select = new int[L];
makeCrypto(0, 0);
System.out.println(sb);
}
private static void makeCrypto(int selectIdx, int elementIdx) {
// 기저조건
if(selectIdx == L) {
// 자음 모음 카운팅
int gatherCnt = 0;
int consonantCnt = 0;
for (int idx = 0; idx < L; ++idx) {
if (alphabet[select[idx]] == 'a'
|| alphabet[select[idx]] == 'e'
|| alphabet[select[idx]] == 'i'
|| alphabet[select[idx]] == 'o'
|| alphabet[select[idx]] == 'u')
gatherCnt++;
else
consonantCnt++;
}
if (gatherCnt > 0 && consonantCnt > 1) {
for (int idx = 0; idx < L; ++idx) {
sb.append(alphabet[select[idx]]);
}
sb.append("\n");
}
return;
}
if(elementIdx == C) {
return;
}
select[selectIdx] = elementIdx;
makeCrypto(selectIdx+1, elementIdx + 1);
makeCrypto(selectIdx, elementIdx + 1);
}
}
3. 디버깅
`select[]`배열에 저장되어있는 값은 `alphabet[]`배열에 대한 인덱스 값이다.
따라서 기저조건에서 자음, 모음 판별 또는 `StringBuilder`에 `append()`할 때, `alphabet[idx]`로 접근하는 것이 아닌, `alphabet[select[idx]]`와 같이 접근해야 한다.