코딩테스트/백준
[BOJ 1759] 암호 만들기(G5)
34suuuuu
2024. 12. 2. 12:08
📍 문제
https://www.acmicpc.net/problem/1759
📍 문제 풀이
가능한 문자를 조합하여 갯수를 구하는 문제 -> 백트래킹
가능한 문자를 조합하여 가능한 문자열을 모두 구하는 문제 -> 백트래킹 + 브루트포스
때문에 이 문제는 백트래킹 + 브루트포스 문제라고 판단했다.
주어진 문자 배열에서 `L`개를 뽑을 때까지 값을 채워나간다.
만약 `L`개를 뽑았다면 그 수가 가능성 있는 암호인지 판단해 가능성 있는 수라면 출력
static void dfs(int start, int cnt) {
if (cnt == L) {
if (isValid()) {
System.out.println(passwords);
}
return;
}
for (int i = start; i < C; i++) {
passwords[cnt] = alphabet[i];
dfs(i + 1, cnt + 1);
}
}
주의해야하는 조건
- 최소 한 개의 모음, 최소 두 개의 자음
- 알파벳이 증가하는 순서
`isValid` 메서드를 통해 자음과 모음의 갯수를 파악해 가능성있는 암호인지 판단하고,
문자를 입력받을 시점에 정렬을 통해 알파벳이 증가하는 순서대로 문자열을 생성할 수 있도록 구현했다.
📍 전체 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class boj_1759 {
static int L,C, cnt;
static char[] alphabet;
static char[] passwords;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
L = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
alphabet = br.readLine().replace(" ", "").toCharArray();
passwords = new char[L];
Arrays.sort(alphabet);
dfs(0, 0);
}
static void dfs(int start, int cnt) {
if (cnt == L) {
if (isValid()) {
System.out.println(passwords);
}
return;
}
for (int i = start; i < C; i++) {
passwords[cnt] = alphabet[i];
dfs(i + 1, cnt + 1);
}
}
public static boolean isValid(){
int vowels = 0; // 모음
int consonants = 0; // 자음
for (char c : passwords) {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
vowels++;
} else {
consonants++;
}
}
if (vowels >= 1 && consonants >= 2) {
return true;
}
return false;
}
}
🙋🏻 다시 한 번 더 알고 넘어가기
일반적으로 배열을 println 메서드로 출력하면 [타입@주소] 형식을 가진다.
배열의 값 자체를 출력하기 위해서는 반복문을 통해 직접 출력하는 방식과 Arrays.toString(배열이름)이 있다.
String[] strings = {"A", "P", "P", "L", "E"};
System.out.println(strings); // [[Ljava.lang.String;@35bbe5e8]
System.out.println(Arrays.toString(strings)); // [A, P, P, L, E]
int[] nums = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(nums)); // [1, 2, 3, 4, 5]
boolean[] types = {true, false, false, true};
System.out.println(Arrays.toString(types)); // [true, false, false, true]
예외적으로 char 배열은 println 메서드로 출력하면 각 요소가 구분자 없이 그대로 출력된다.
import java.util.Arrays;
public class Print_test {
public static void main(String[] args) {
char[] chars = {'a', 'p', 'p', 'l', 'e'};
System.out.println(chars); // [apple]
String[] strings = {"A", "P", "P", "L", "E"};
System.out.println(strings); // [[Ljava.lang.String;@35bbe5e8]
System.out.println(Arrays.toString(strings)); // [A, P, P, L, E]
}
}