https://www.acmicpc.net/problem/1759
1759번: 암호 만들기
첫째 줄에 두 정수 L, C가 주어진다. (3 ≤ L ≤ C ≤ 15) 다음 줄에는 C개의 문자들이 공백으로 구분되어 주어진다. 주어지는 문자들은 알파벳 소문자이며, 중복되는 것은 없다.
www.acmicpc.net
풀이
문제를 보고 조합을 이용해야겠다는 생각이 들었다.
암호에는 알파벳을 중복하여 사용할 수 없고, 암호를 이루는 알파벳이 증가하는 순서로 배열되어야 한다.
즉, 입력받는 C개의 문자를 배열에 저장하여 알파벳 순으로 정렬하고, 배열 인덱스(0 ~ C-1)의 모든 조합의 경우의 수를 구하면, 가능성 있는 암호의 모든 경우를 구할 수 있다.
조합은 DFS로 구현한다.
조합을 구현하는 기본 틀은 다음과 같다.
백준 15650 N과 M (2)
https://www.acmicpc.net/problem/15650
import java.io.*;
import java.util.*;
public class Main {
static int n, m;
static int[] comb;
static StringBuilder sb = new StringBuilder();
static public void combination(int L, int start) {
if (L == m) {
for (int i : comb)
sb.append(i + " ");
sb.append("\n");
}
else {
for (int i = start; i <= n; i++) {
comb[L] = i;
combination(L+1, i+1);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
comb = new int[m];
combination(0, 1);
System.out.println(sb);
}
}
참고: JAVA 순열, 중복 순열, 조합, 중복 조합 구현
주의할 점
"암호는 서로 다른 L개의 알파벳 소문자들로 구성되며 최소 한 개의 모음(a, e, i, o, u)과 최소 두 개의 자음으로 구성되어 있다고 알려져 있다."
조합으로 구한 완성된 암호에서 모음의 개수가 1개 이상이어야 하고, 자음의 개수가 2개 이상인지 체크해줘야 한다.
코드
import java.io.*;
import java.util.*;
public class Main {
static StringBuilder sb = new StringBuilder();
static String[] word;
static int[] comb;
static int L, C;
public static boolean check(String str) {
if (str.equals("a") || str.equals("e") || str.equals("i") || str.equals("o") || str.equals("u"))
return true;
else return false;
}
public static void combination(int idx, int start) {
if (idx == L) {
StringBuilder tmp = new StringBuilder();
int cnt = 0; // 모음의 개수
for (int n : comb) {
tmp.append(word[n]);
if (check(word[n]))
cnt++;
}
if (cnt >= 1 && L-cnt >= 2)
sb.append(tmp+"\n");
return;
}
for (int i = start; i < C; i++) {
comb[idx] = i;
combination(idx+1, i+1);
}
}
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());
word = new String[C];
comb = new int[L];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < C ; i++) {
word[i] = st.nextToken();
}
Arrays.sort(word);
combination(0, 0);
System.out.println(sb);
}
}
728x90
'Algorithm 문제 풀이 > 백준' 카테고리의 다른 글
[백준] 1987번 : 알파벳 - 자바[Java] (0) | 2022.09.10 |
---|---|
[백준] 10994번 : 별 찍기 - 19 - 자바[Java] (0) | 2022.09.10 |
[백준] 1244번 : 스위치 켜기 - 자바[Java] (0) | 2022.09.09 |
[백준] 4396번 : 지뢰찾기 - 자바[Java] (0) | 2022.09.09 |
[백준] 2578번 : 빙고 - 자바[Java] (0) | 2022.09.09 |