-
1759 암호 만들기(자바)백준/브루트 포스 2022. 2. 3. 22:31
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.StringTokenizer; public class Main { static int N; static int M; static String input[]; static boolean check[]; static String word; static StringBuilder result; 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()); check = new boolean [M]; result = new StringBuilder(); input = new String[M]; StringTokenizer st1 = new StringTokenizer(br.readLine(), " "); for(int i=0;i<M; i++) { input[i] = (String) st1.nextToken(); } Arrays.sort(input); dfs(0, 0); } public static void dfs(int start, int depth) { if(depth==N) { for(int i=0; i<M;i++) { if(check[i]) { result.append(input[i]); } } word = result.toString(); result.setLength(0); int count = 0; if(word.contains("a")) count++; if(word.contains("o")) count++; if(word.contains("u")) count++; if(word.contains("e")) count++; if(word.contains("i")) count++; if(1 <= count && count <= N-2) { System.out.println(word); } } for(int i =start; i<M;i++) { check[i]=true; dfs(i+1, depth+1); check[i]=false; } } }
이전에 풀었던 로또문제(백준 6603) 이랑 비슷해서 비교적 수월하게 풀었다.
https://happy-fun.tistory.com/196?category=981765
6603 로또 (java)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { static int number[]; static boolean result[]; stati..
happy-fun.tistory.com
dfs 를 이용해서 완성했다.
코드를 설명해보겠다.
N : 암호 길이 // 4
M : 입력 받은 문자 개수 //6
input 배열 : 입력 받은 문자를 input 배열에 넣음. 그리고나서 배열을 오름차순 정렬하기 때문에
최종적으로 input 배열에는
a c i s t w 순으로 저장된다.
check 배열과 result 변수는 아래에서 설명하겠다.
---------------------------------
dfs 메서드를 살펴보자.
우리는 dfs(0,0) 부터 시작한다.
그럼 일단 아래 부분부터 살펴보자.
for(int i =start; i<M;i++) { check[i]=true; dfs(i+1, depth+1); check[i]=false; }
dfs(0,0) 이므로,
start = 0, depth =0 이다.
그리고 check 배열에 설명하자면
타입이 boolean 으로
처음에는 모든 값이 false 로 초기화 되어 있다.
하지만 위에서 보듯이 check 배열의 값을 true 로 바꿔주고 있다.
이를 설명해보겠다.
input 배열에는 다음과 같이 저장되어 있다.
a c i s t w
만약 check 배열의 값들이 true true false false true true 로 되었다고 하자.
이때 우리는 true 의 값을 가지고 있는 인덱스, 즉 여기서는 0,1,4,5 에 해당하는
input 배열의 값을 찾아서,
즉 a c t w
출력할 것이다.
이게 가능하도록 아래 코드 완성
if(depth==N) { for(int i=0; i<M;i++) { if(check[i]) { result.append(input[i]); } } word = result.toString(); result.setLength(0); int count = 0; if(word.contains("a")) count++; if(word.contains("o")) count++; if(word.contains("u")) count++; if(word.contains("e")) count++; if(word.contains("i")) count++; if(1 <= count && count <= N-2) { System.out.println(word); } }
depth==N, 즉 여기서는 4를 만족하게 되면
check 배열의 true 값이 4개가 된다.
이때 check 배열의 인덱스에 해당하는 input 배열의 글자를 출력해서
길이가 4인 암호를 출력한다.
예를들어,
아래와 같다.
input 배열은 a c i s t w 이고,
그 아래 check 배열의 상태, 그 인덱스에 해당되는 input 배열의 글자이다.
이와 더불어 모음이 1글자 이상, 자음이 2글자 이상인 조건을 만족하는 글자를 최종적으로 출력하게 한 것이다.
그리고 여기서 보면, StringBuilder 타입의 result 변수에 글자들을 추가한 다음
String 타입의 word 에 옮겨 담아서 출력하는 것을 알 수 있다.
이는, StringBuilder 의 append 메서드를 사용하기 위함이다.
String 타입에서는 글자에 다른 글자를 추가할 때 concat 라는 메서드를 사용하는데,
이 메서드는 2개의 글자를 합쳐서 출력해줄 뿐, A 단어에 B 단어를 붙여서 유지해주지 않는 듯 했다.
그래서 StringBuilder 를 이용해서 글자들을 이어붙이고 다시 String 타입의 word 변수에 옮겨 담았다.
더불어서
result.setLength(0);
이 코드로 result 변수를 초기화 한 뒤,
새로운 단어를 담도록 했다.
이 사진에서도 볼 수 있지만,
맨 처음에는 t t t t f f 이지만
그 아래는 t t t f t f 이다.
즉, 인덱스 3의 위치 t 값이 그 다음에는 f 로 변해있는데,
for(int i =start; i<M;i++) { check[i]=true; dfs(i+1, depth+1); check[i]=false; }
이 코드에서 보이듯이, dfs() 메서드를 마치고 돌아와서는 다시 false 로 바꾸기 때문이다.
'백준 > 브루트 포스' 카테고리의 다른 글
14500 테트로미노 (0) 2022.04.24 2501 약수 구하기(자바) (0) 2022.02.19 1065 한수 (0) 2022.02.08 2798 블랙잭 (0) 2021.10.18