모르겠다.
결국 답지봄. 조합을 기깔나게 쓰는 문제다.
import java.io.*;
import java.util.*;
class Main{
static int N,K;
static boolean[] visited = new boolean[26];
static String[] word;
static List<Integer> path = new ArrayList<>();
static int ans = Integer.MIN_VALUE;
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());//50이하
K = Integer.parseInt(st.nextToken());//0~26
word = new String[N];
for(int i=0;i<N;i++){
String s = br.readLine();
s = s.replace("anta", "");
s = s.replace("tica", "");
word[i] = s;
}
//a n t i c 는 이미 안다.
//K개를 새로 배우면 된다.
//26개중 K개를 중복없이 선택하는 경우 * N
// for(int i = (int)'a' ; (int)'a'+26 > i ; i++){
// if((char)i == 'a') continue;
// if((char)i == 'n') continue;
// if((char)i == 't') continue;
// if((char)i == 'i') continue;
// if((char)i == 'c') continue;
// candidateChar.add((char)i);
// }
if(K<5) {
System.out.print(0);
return;
}else if(K == 26){
System.out.print(N);
return;
}
//알아서 정수계산 되더라~
visited['a' - 'a'] = true;
visited['n' - 'a'] = true;
visited['t' - 'a'] = true;
visited['i' - 'a'] = true;
visited['c' - 'a'] = true;
backtracking(0,0);
System.out.print(ans);
}
//백트래킹으로 조합을 구현. 조합은 순서가 없기에 start로 불필요한 연산을 줄이자.
static void backtracking(int depth, int start){
//끝내는 조건문 잊지말고, 마지막에 return 도 잊지마.
if(depth == K - 5){
int cnt = 0;
for(String w : word){
boolean canRead = true;
for(int i=0;i<w.length();i++){
if(!visited[(int)w.charAt(i)-(int)'a']){
canRead = false;
break;
}
}
if(canRead) ++cnt;
}
ans = Math.max(ans,cnt);
//System.err.println(path);
return;
}
for(int i=start ; i<26 ; i++){
if(visited[i]) continue;
visited[i] = true;
//path.add(i);
backtracking(depth+1,i+1);
visited[i] = false;
//path.remove(path.size()-1);
}
}
}