알고리즘

백준 온라인저지 5052 번 전화번호 목록

추운남자06 2019. 5. 12. 18:03

TRIE 를 비교적 쉽게 풀 수 있었던 문제 

 

TRIE 를 쓰지 않으면 , 전체 스트링을 비교해야 되니까? O(n^2) 의 알고리즘이 

 

TRIE 를 써서  O(n) 의 속도로 줄어들 은 것 같다. 

 

처음에는 add 를 하면서 바로 NO 인 케이스를 발견해내는 방법으로 진행했는 데

 

12345 가 들어오고 123 이 들어오면 괜찮으나 반대로 123 이 들어오고 12345 가 

 

들어오면 구현이 어려워지는 문제점이 있어서 다른 곳에서 본 대로 , 먼저 add 로 

 

전부 저장해 놓은 후에 , 추후에 find 를 해가면서 NO 를 발견하는 구조로 갔다. 

 

#include 

using namespace std;

#define INTEGER_NUM 10
#define MAX_TREE_SIZE 2000000
#define MAX_NUM 10000

struct NODE {
bool isWord;
NODE* children[INTEGER_NUM];
}nodes[MAX_TREE_SIZE];

int nodes_cnt = 0;

NODE* myalloc() {

for (int i = 0; i < INTEGER_NUM; i++) {
nodes[nodes_cnt].children[i] = NULL;
}
nodes[nodes_cnt].isWord = false;
return &nodes[nodes_cnt++];
}

void add(NODE* root, char* str) {
NODE* c = root;

for (int i = 0; str[i]; i++) {

int nextIdx = str[i] - '0';

if (c->children[nextIdx]) {
c = c->children[nextIdx];
}
else {
NODE* newNode = myalloc();
c->children[nextIdx] = newNode;
c = c->children[nextIdx];
}
}
c->isWord = true;
}

int find(NODE* root, char* str) {
NODE* c = root;

for (int i = 0; str[i]; i++) {
if (c->isWord == true)
return 0;

int nextIdx = str[i] - '0';

c = c->children[nextIdx];
}
return 1;
}

void init() {
nodes_cnt = 0;
}

int canAdd() {
int wordCnt;
char inputStr[MAX_NUM][11];
NODE* root = myalloc();

cin >> wordCnt;

for (int i = 0; i < wordCnt; i++)
{
cin >> inputStr[i];
add(root, inputStr[i]);
}
for (int i = 0; i < wordCnt; i++)
{
if (!find(root, inputStr[i]))
return 0;
}
return 1;
}

int main()
{
int total;

cin >> total;

for (int i = 0; i < total; i++)
{
// 초기화 
init();

if (!canAdd())
cout << "NO" << endl;
else
cout << "YES" << endl;
}
}