출처 : https://www.acmicpc.net/problem/5670
5670번: 휴대폰 자판
휴대폰에서 길이가 P인 영단어를 입력하려면 버튼을 P번 눌러야 한다. 그러나 시스템프로그래밍 연구실에 근무하는 승혁연구원은 사전을 사용해 이 입력을 더 빨리 할 수 있는 자판 모듈을 개발
www.acmicpc.net
고려사항
- 트라이 자료구조 사용
- 매 테스트 케이스마다 다른 사전 구성이니 꼭 delete root 로 메모리 관리하기.
- 단어의 첫 글자를 추론하지 않는다 => 2번째 테스트 케이스처럼 모든 단어가 한 알파벳으로 시작하면
코드의 로직은 총 버튼 클릭수를 정답보다 n 번만큼 뺀 만큼 구한다. root의 nextCnt 가 1이라 +1을 안해주기 때문!
따라서 root->nextCnt == 1 이라면 sum += n 실행!
- hell, hello 의 경우를 잘 분석한다 => 다음 알파벳이 하나 뿐이고, 현재 알파벳에서 term 이라면 ++nextCnt
- scanf는 입력 받은 인자? 수 를 return 한다 => eof 시 -1
#include <cstdio>
using namespace std;
struct trie{
bool term;
int nextCnt;
trie *next[26];
trie(){
term = false;
nextCnt = 0;
for(int i=0;i<26;++i){
next[i] = NULL;
}
}
~trie(){
for(int i=0;i<26;++i){
delete next[i];
}
}
void insert(char *str){
if(*str == '\0'){
++nextCnt;
term = true;
}else{
int tmp = *str - 'a';
if(!next[tmp]){
next[tmp] = new trie();
++nextCnt;
}
next[tmp]->insert(str+1);
}
}
int find(char *str, int cnt){
if(*str == '\0'){
if(term){
return cnt;
}else{
return -1;
}
}else{
int tmp = *str - 'a';
if(!next[tmp]){
return -1;
}else{
if(nextCnt == 1){
return next[tmp]->find(str+1, cnt);
}
return next[tmp]->find(str+1, cnt+1);
}
}
}
};
int main() {
int n;
float sum, ans;
char str[100000][81];
while(scanf("%d", &n) > 0){
trie *root = new trie();
sum = 0;
for(int i=0;i<n;++i){
scanf("%s", str[i]);
root->insert(str[i]);
}
for(int i=0;i<n;++i){
sum += root->find(str[i], 0);
}
if(root->nextCnt == 1){
sum += n;
}
ans = sum / n;
printf("%.2f\n", ans);
delete root;
}
return 0;
}
'BOJ 백준 > 문자열' 카테고리의 다른 글
백준 09935 - 문자열 폭발 (0) | 2020.11.12 |
---|---|
백준 14425 - 문자열 집합 (0) | 2020.11.07 |
백준 10988 - 팰린드롬인지 확인하기 (0) | 2020.01.07 |
백준 10545 - 뚜기뚜기메뚜기 (0) | 2020.01.04 |