题意
给定一组字符串, 找出每个字符串的最短可识别的缩写前缀
如果到串尾也无法特定识别, 标志为整个串
题解
字典树 + 构造时前缀串
AC code:
/*
* Author : adrui
* Language : C++
* Result : Accepted
* Love : yy
* Favorite : Dragon Balls
* Standing in the Hall of Fame
*/
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
#define debug 0
#define LL long long
#define inf 0x7f7f7f7f
#define mod 10003
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1|1, mid + 1, r
#define M(a, b) memset(a, b, sizeof(a))
const int maxn = 1000 + 5;
int idx(char p) {
return p - 'a';
}
struct trie {
int v;
bool exist;
char word[22];
trie *next[26];
trie() {
v = 0;
exist = false;
M(next, 0);
}
char* query(char *s) {
int len = strlen(s);
trie *rt = this;
for (int i = 0; i < len; ++i) {
int c = idx(s[i]);
rt = rt->next[c];
if (rt->v == 1 || i == len - 1) return rt->word;//只出现一次可标识或者是到了串尾
}
}
void insert(char *s) {
trie *rt = this;
int len = strlen(s);
for (int i = 0; i < len; ++i) {
int c = idx(s[i]);
if (!rt->next[c]) {
rt->next[c] = new trie;
}
rt = rt->next[c];
++rt->v;
strncpy(rt->word, s, i + 1);
rt->word[i + 1] = '\0'; //前缀串
//cout << rt->word << endl;
}
rt->exist = true;
}
};
int main() {
#if debug
freopen("in.txt", "r", stdin);
#endif //debug
cin.tie(0);
cin.sync_with_stdio(false);
char s[maxn][22];
trie rt;
int cnt = 0;
while (cin >> s[cnt]) {
rt.insert(s[cnt]);
++cnt;
}
for (int i = 0; i < cnt; ++i) {
cout << s[i] << " " << rt.query(s[i]) << endl;
}
return 0;
}