1062번: 가르침
첫째 줄에 단어의 개수 N과 K가 주어진다. N은 50보다 작거나 같은 자연수이고, K는 26보다 작거나 같은 자연수 또는 0이다. 둘째 줄부터 N개의 줄에 남극 언어의 단어가 주어진다. 단어는 영어 소문
www.acmicpc.net
뭔가 카카오 코딩테스트에서 많이 나올법만 문제 유형이였다.
K개의 단어를 학습하려고 하고 anti - tica는 무조껀 단어에 존재한다고 하니까 5글자는 무조껀 학습이 되어야하는 상황이다.
그렇다면 K<5, K>=5인 경우로 크게 나눠볼 수 있고
배워야하는 단어의 수 : X 라고 한다면
X < K-5라면 무조껀 X는 다 배울 수 있기 때문에 주어진 단어를 모두 다 배울 수 있다.
X >= K-5라면, X개 중 K-5개를 뽑아서 check()해봐야하기 때문에 조합이 적용된다.
Q) 왜 K-5일까? K개를 학습할 수 있는데 anti - tica때문에 5글자는 무조껀 기본으로 들어가고 K-5개를 추가적으로 학습할 수 있는 선택지가 있기 때문에 총 배울 수 있는 선택지들 중에서 K-5개를 뽑는 조합이 들어가는 것이다.
근데 X < K-5라면 X를 모두 학습하더라도 남기 때문에 모든 단어를 다 배울 수 있다는 뜻이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
/*
* K개의 글자로만 이루어진 단어만 읽을 수 있음
* 어떤 K개의 글자를 가르쳐야 학생들이 읽을 수 있는 단어의 개수가 최대가 될까
*
* anta - tica
* a:3, c:1, i:1, t:2, n:1
*
* 기본적으로 5글자는 알아야 단어를 읽을 수 있는 권한이 생김
* K<5면 그냥 0
* K>=5라면 어떤 단어를 추가했을 때 가장 적절한지 일일히 확인 해보기
*
* substring으로 일일이 단어를 뺄 수 있고 어떤 알파벳이 필요한지 리스트를 뽑아낼 수 있으며
* 총 몇개 중 K-5개를 뽑았을 떄 그때의 최댓값이니까 조합으로 풀면될 듯?
*
*
* */
public class Main{
static int res;
static int N,K;
static List<Character> list;
static String[] data;
static boolean[] alphabet;
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());
K = Integer.parseInt(st.nextToken());
data = new String[N];
alphabet = new boolean[26];
alphabet['a'-'a'] = true;
alphabet['c'-'a'] = true;
alphabet['i'-'a'] = true;
alphabet['t'-'a'] = true;
alphabet['n'-'a'] = true;
list = new ArrayList<>();
for (int i = 0; i < N; i++) {
String temp = br.readLine();
int str_length = temp.length();
data[i] = temp.substring(4, str_length-4);
for (int j = 0; j < data[i].length(); j++) {
if (!alphabet[data[i].charAt(j) - 'a']){
list.add(data[i].charAt(j));
alphabet[data[i].charAt(j) - 'a'] = true;
}
}
}
for (int i = 0; i < list.size(); i++) {
alphabet[list.get(i) - 'a'] = false;
}
if (K <5)
System.out.println(0);
else{
res = 0;
// System.out.println(Arrays.toString(data));
// System.out.println(list.toString());
if (list.size() <= K-5)
res = data.length;
// 여기서 조합을 한다고 치자
// r을 골랐다고 했으면 r을 골랐을 때 몇개를 알 수 있는지 check()는 어케함?
// for data해서 5개말고 고른 알파벳이 있다면 res++
combi(0, 0, new char[K-5]);
System.out.println(res);
}
}
public static void combi(int start, int depth, char[] select){
if (depth == (K-5)){
// System.out.println(Arrays.toString(data));
// System.out.println(list.toString());
// visited = true;
for (int i = 0; i < select.length; i++) {
alphabet[select[i] - 'a'] = true;
}
int cnt = 0;
for (int i = 0; i < data.length; i++) {
boolean flag = true;
for (int j = 0; j < data[i].length(); j++) {
if (!alphabet[data[i].charAt(j) - 'a']) {
flag = false;
break;
}
}
if (flag)
cnt++;
}
res = Math.max(res,cnt);
// visited = false;
for (int i = 0; i < select.length; i++) {
alphabet[select[i] - 'a'] = false;
}
return ;
}
for (int i = start; i < list.size(); i++) {
select[depth] = list.get(i);
combi(i+1,depth+1,select);
}
}
}
'Algorithm > Algorithm Problem' 카테고리의 다른 글
백준 2133 타일 채우기(DP) (1) | 2022.12.23 |
---|---|
백준 14238 출근 기록(DFS+DP) ★ (0) | 2022.12.16 |
SWEA 1983 조교의 성적 매기기(Map) (0) | 2022.11.04 |
SWEA 1859 백만 장자 프로젝트(그리디) ★★ (0) | 2022.11.03 |
백준 3687 성냥개비(DP, 그리디) (0) | 2022.10.31 |