当前位置: 代码迷 >> 综合 >> poj - 2001 - Shortest Prefixes(Trip)
  详细解决方案

poj - 2001 - Shortest Prefixes(Trip)

热度:35   发布时间:2024-01-10 13:24:57.0

题意:有若干个由小写字母组成的名字,对于每个名字,只取它的最短前缀,使得这些取出来的前缀互不相同,输出原名及取出的前缀(2 <= 名字个数 <= 1000, 1 <= 每个名字的长度 <= 20)。

题目链接:http://poj.org/problem?id=2001

——>>又一道前缀树Trip题目呀~

设cnt[i]为第i个结点有多少个名字经过,那么,若cnt[i]为1,则表明只有1个名字经过,下面只表示1个人,输出每个前缀时到此停止;若cnt[i] > 1,则表明不止1个名字经过,必须往下扫描,直到能分辨出来为止。

#include <cstdio>
#include <cstring>using namespace std;const int maxn = 1000 + 10;
const int maxw = 20 + 5;
char name[maxn][maxw];
int n;struct node{int cnt;node *next[26];node(){cnt = 0;memset(next, 0, sizeof(next));}
};struct Trip{node *root;Trip(){root = new node;}int idx(char c){return c - 'a';}void insert(char *s){int len = strlen(s), i;node *t = root;for(i = 0; i < len; i++){int c = idx(s[i]);if(!t->next[c]) t->next[c] = new node;t->next[c]->cnt++;t = t->next[c];}}void solve(){int i, j, c;for(i = 0; i < n; i++){printf("%s ", name[i]);node *t = root;int len = strlen(name[i]);for(j = 0; j < len; j++){c = idx(name[i][j]);putchar(name[i][j]);if(t->next[c]->cnt == 1) break;t = t->next[c];}putchar('\n');}}
};int main()
{n = 0;Trip trip;while(scanf("%s", name[n]) == 1) trip.insert(name[n++]);trip.solve();return 0;
}


  相关解决方案