题意 : 给你一些字符串,让你为每个字符串找一个最短的前缀,来唯一标识这个字符串,与其他字符串区别开来.这个标志串不能是其他字符串的前缀,除非这个标志串等于这个字符串本身. 考虑用字典树来做.标志当前位是否是结尾位,作为一个边界条件.先将所有字符串按长度排序,每次对一个字符串按位插入字典树里,将路过的位置num加1.最后,如果当前位的num是1,说明到当前位为止的前缀可以唯一标志这个字符串,保存这个前缀. 看提交记录里,好多人都六七百B的代码,而我的代码居然达到了2000B…….果然还是水平不精,实现相同的效果代码还要比人家长,需要多多磨练. ———————————————————————————————————–
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
A prefix of a string is a substring starting at the beginning of the given string. The prefixes of “carbon” are: “c”, “ca”, “car”, “carb”, “carbo”, and “carbon”. Note that the empty string is not considered a prefix in this problem, but every non-empty string is considered to be a prefix of itself. In everyday language, we tend to abbreviate words by prefixes. For example, “carbohydrate” is commonly abbreviated by “carb”. In this problem, given a set of words, you will find for each word the shortest prefix that uniquely identifies the word it represents.
In the sample input below, “carbohydrate” can be abbreviated to “carboh”, but it cannot be abbreviated to “carbo” (or anything shorter) because there are other words in the list that begin with “carbo”.
An exact match will override a prefix match. For example, the prefix “car” matches the given word “car” exactly. Therefore, it is understood without ambiguity that “car” is an abbreviation for “car” , not for “carriage” or any of the other words in the list that begins with “car”.
输入
- The input contains at least two, but no more than 1000 lines. Each line contains one word consisting of 1 to 20 lower case letters. 输出
- The output contains the same number of lines as the input. Each line of the output contains the word from the corresponding line of the input, followed by one blank space, and the shortest prefix that uniquely (without ambiguity) identifies this word. 样例输入
-
carbohydrate cart carburetor caramel caribou carbonic cartilage carbon carriage carton car carbonate
样例输出
-
carbohydrate carboh cart cart carburetor carbu caramel cara caribou cari carbonic carboni cartilage carti carbon carbon carriage carr carton carto car car carbonate carbona
来源
- Rocky Mountain 2004
/*
内存: 852kB
时间: 4ms
语言: G++
*/
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
int total, len, flag;
char ini[1010][21], res[1010][21];
struct zifuchuan
{
int num;
char str[22];
}s[11000];
struct tree
{
tree *son[27];
char val;
int tail;
int num;//记录当前这个字母在这个位置出现了多少次
tree(){
num = 0;
for(int i=0;i<27;i++)
{
son[i] = NULL;
}
tail = 0;
}
};
bool cmp(zifuchuan a,zifuchuan b)
{
return strlen(a.str)<strlen(b.str);
}
void insert(tree *&root,char *a,int _index)
{
if(_index >= len)
return;
if(root->son[a[_index]-'a'] == NULL)
{
tree *t = new tree;
t->val = a[_index];
if(_index == len-1)
t->tail = 1;
t->num = 1;
root->son[a[_index]-'a'] = t;
insert(root->son[a[_index]-'a'],a,_index+1);
//cout<<"HHHHHHHHHHHHHHHH "<<root->son[a[_index]-'0']->val<<endl;
}
else
{
root->son[a[_index]-'a']->num++;
insert(root->son[a[_index]-'a'],a,_index+1);
}
}
int main()
{
while(scanf("%s",&s[total].str) != EOF)
{
s[total].num = total;
strcpy(ini[total],s[total].str);
total++;
}
//cout<<"???????????"<<endl;
tree *root = new tree;
sort(s,s+total,cmp);
for(int i=0;i<total;i++)
{
len = strlen(s[i].str);
insert(root,s[i].str,0);
}
for(int i=0;i<total;i++)
{
len = strlen(s[i].str);
tree *temp = root;
for(int j=0;j<len;j++)
{
temp = temp->son[s[i].str[j]-'a'];
if(temp->tail == 1)
{
temp->num++;
temp->tail = 0;
for(int k=0;k<=j;k++)
res[s[i].num][k] = s[i].str[k];
break;
}
if(temp->num == 1)
{
temp->num++;
for(int k=0;k<=j;k++)
res[s[i].num][k] = s[i].str[k];
break;
}
}
}
for(int i=0;i<total;i++)
printf("%s %s\n",ini[i],res[i]);
return 0;
}