大意:给定一些字符串,让你找到每一个字符串的最小前缀,该前缀能唯一代表该字符串。
思路:字典树,维护一个val值,表示通过该结点的字母的个数,只要val[i] == 1,返回该字母的位置,如果都没有,直接返回字符串长度。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int n;
const int sigma_size = 26;
const int maxnode = 10010;
char str[1010][30];
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int flag[maxnode];
int sz;
void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
int idx (char c) { return c-'a'; }
void insert(char *s, int v)
{
int u = 0, n = strlen(s);
for(int i = 0; i < n; i++)
{
int c = idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
val[u]++;
}
}
int find(char *s)
{
int u = 0, n = strlen(s);
for(int i = 0; i < n; i++)
{
int c = idx(s[i]);
u = ch[u][c];
if(val[u] == 1) return i;
}
return n-1;
}
};
Trie trie;
void solve()
{
for(int i = 0; i < n; i++)
{
printf("%s ", str[i]);
int p = trie.find(str[i]);
for(int j = 0; j <= p; j++) printf("%c", str[i][j]);
printf("\n");
}
}
int main()
{
n = 0;
trie.init();
while(~scanf("%s", str[n]))
{
trie.insert(str[n], -1);
n++;
}
solve();
return 0;
}