题目大意就是帮你给N条字符串,每条长度不超过20。问要将他们单一识别出来,每个字符串最短可以缩为多短。
如:
abc
abcdefg
bc
adef
这四个字符串就可分别缩写为
abc
abcd
b
ad
方法: 字典树(可以参阅http://s.acmore.net/show_article/show/58)。
另外我还用了一个bool数组last用来记录每个单一识别的字符串最短可以到哪个位置,他的下标就是字典树中每个字母对应的序号
方法如下:(以上面的为例)
当输入的字符串在某一个位置开始与之前的不同,就记录这个不同的字母(设置为true),之后的不再改变
当输入字符串的某位置在建好的树中时,把last加长(设置为true)
第一次输入:abc last[0]=true;
第二次输入:abcdefg last[0]=last[1]=last[2]=last[3]=true;
第三次输入:bc last[0]=true;
第四次输入:adef last[0]=last[1]=true;
这样一来输出端长度就分别为1、4、1、2
代码实现如下:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define MAX(a,b) (a) > (b)? (a):(b) 9 #define MIN(a,b) (a) < (b)? (a):(b)10 #define mem(a) memset(a,0,sizeof(a))11 #define INF 100000000712 #define MAXN 2000513 using namespace std;14 15 int trie[MAXN][26],val[MAXN],S;16 bool last[MAXN];17 char ma[1005][30];18 19 int get_num(char ch){ return ch-'a';}20 21 void init()22 {23 mem(trie);mem(val);24 mem(last);mem(ma);25 S = 1;26 }27 28 void insert(char *s)29 {30 int u=0,len = strlen(s);31 int flag = 1;32 for(int i=0;i