题目描述
解题思路
题目大意:
给出每个字符串的最短前缀表示,且不与其他字符串的表示相冲突。
Trie中依次访问字符串的每个字符,若当前 字符节点 只被一个字符串所到达,则最短前缀即为从根节点到当前节点所构成的字符串。
参考代码
//**********************************************
// Author: @xmzyt1996
// Date: 2015-10-16
// Name: POJ 2001.cpp
//**********************************************
#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <bitset>
#include <vector>
#include <stack>
#include <queue>
#include <map>
using namespace std;
#define clr(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i < b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
#define pt(x) cout << #x << " = " << x << endl
#define ps puts("debug~~")
#define all(x) (x).begin(),(x).end()
#define mp make_pair
#define pb push_back
typedef __int64 ll;
typedef pair<int, int> pii;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int MAX_N = 1010;
struct Trie {
int next[26], cnt;
}node[MAX_N*10];
int num;
void init() {
num = 0;
memset(node, 0, sizeof(node));
}
int getid(char c) { return c - 'a'; }
void insert(char* s) {
Trie* head = &node[0];
while (*s) {
int id = getid(*s++);
if ((head->next[id]) == NULL)
head->next[id] = &node[++num];
head = head->next[id];
(head->cnt)++;
}
}
void search(char* s) {
Trie* head = &node[0];
char *p = s, ss[25];
int k = 0;
while (*s) {
ss[k++] = *s;
int id = getid(*s++);
head = head->next[id];
if ((head->cnt) == 1) { // 当前字符节点只被一个字符串所到达
ss[k] = 0;
printf("%s %s\n", p, ss);
return ;
}
}
printf("%s %s\n", p, p);
}
char s[MAX_N][25];
int main() {
int k = 0;
init();
while (~scanf("%s", s[k])) insert(s[k++]);
rep(i, 0, k) search(s[i]);
return 0;
}