문제 풀이/백준
[백준]1062번. 가르침(JAVA)
27200
2024. 4. 14. 15:22
https://www.acmicpc.net/problem/1062
문제
풀이
import java.io.*;
import java.util.*;
public class Main {
static int n, k;
static int max = Integer.MIN_VALUE;
static boolean[] visited;
static String[] word;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());
word = new String[n];
for(int i = 0; i < n; i++){
String str = br.readLine();
word[i] = str.substring(4,str.length() - 4);
}
if(k<5){
System.out.println(0);
return;
} else if (k == 26) {
System.out.println(n);
return;
}
visited = new boolean[26]; //각 알파벳을 배웠는지 체크
visited['a' - 'a'] = true;
visited['c' - 'a'] = true;
visited['i' - 'a'] = true;
visited['n' - 'a'] = true;
visited['t' - 'a'] = true;
dfs(0,0);
System.out.println(max);
}
public static void dfs(int index, int len){
if(len == k-5){
int count = 0;
for(int i = 0; i < n; i++){
boolean check = true;
for(int j = 0; j < word[i].length(); j++){
if(!visited[word[i].charAt(j) - 'a']){
check = false;
break;
}
}
if(check) count++;
}
max = Math.max(max, count);
return;
}
for(int i = index; i < 26; i++) {
if(visited[i] == false) {
visited[i] = true;
dfs(i+1, len + 1);
visited[i] = false;
}
}
}
}
천천히 살펴보자.
먼저 사용자 입력을 받은 문자열에서 앞의 네글자와 뒤의 네글자를 제외하고 받는다.(필수적으로 들어오는 문자이기 때문이다)
후에 배울 수 있는 문자의 크기가 5보다 작거나 26과 동일하다면 예외적으로 바로 답을 출력한다.(이런 식으로 가능하다면 먼처 처리하고 끝내는 것이 효율이 좋다.)
알파벳 26개에 대해 인덱스를 두고 학습을 진행할 것이다. 대신 꼭 배워야하는 antic에 대해서는 먼저 true처리를 해준다.
이때 꼭 알면 좋은 것이 'a'-'a'가 알파벳의 0번 인덱스이다! 즉 알파벳 - 'a'를 해주면 내가 알고있는 순서가 나오게 된다.
이후 dfs부분에서는 백트레킹과 조합을 이용한 방식이다.
len이 k-5가 될때까지 진행한다.
a부터 인덱스를 하나씩 순회하며 모든 조합을 테스트해볼 때까지 진행하며 이 때마다 max값이 갱신될 수 있음을 확인해주면 된다.