poj2001:http://poj.org/problem?id=2001
题意:给你一些单词,然后让你寻找每个单词的一个前缀,这个前缀能够唯一表示这个单词,并且是最短的。
题解:直接用trie树来搞。每个节点维护一个val值,每次插入经过该点值,把该点val加1,然后查询的时候,如果当前节点val是1,则说明只有一个串经过这里,此时就可以停止输出,返回即可。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define maxn 1100000 6 using namespace std; 7 struct Nod { //0为无效值 8 int lnk[26], val; 9 void init() { 10 memset(lnk, 0, sizeof(lnk)); 11 val = 0; 12 } 13 }; 14 const char BASE = 'a'; 15 struct Trie { 16 Nod buf[maxn]; 17 int len; 18 void init() { 19 buf[len=0].init(); 20 } 21 void insert(char * str) { 22 int now = 0; 23 for(int i = 0; str[i]; i ++) { 24 int & nxt = buf[now].lnk[str[i]-BASE]; 25 if(!nxt)buf[nxt=++len].init(); 26 now = nxt; 27 buf[now].val++; 28 } 29 } 30 void search(char * str) { 31 int now = 0; 32 for(int i = 0; str[i]; i ++) { 33 int & nxt = buf[now].lnk[str[i]-BASE]; 34 printf("%c",str[i]); 35 if(buf[nxt].val==1){ 36 printf(" "); 37 return; 38 } 39 //if(!nxt) return 0; 40 now = nxt; 41 } 42 printf(" "); 43 } 44 } trie; 45 char str[1002][50]; 46 int main(){ 47 int top=0; 48 trie.init(); 49 while(~scanf("%s",str[++top])){ 50 trie.insert(str[top]); 51 } 52 for(int i=1;i<=top;i++){ 53 printf("%s ",str[i]); 54 trie.search(str[i]); 55 } 56 }