#1107 : Shortest Proper Prefix

来源:互联网 发布:网络分层物理层 编辑:程序博客网 时间:2024/05/23 00:56

题目描述:

#1107 : Shortest Proper Prefix

时间限制:10000ms
单点时限:1000ms
内存限制:512MB

描述

14214822852319.png

Query auto-completion(QAC) is widely used in many search applications. The basic idea is that when you type some string s in the search box several high-frequency queries which have s as a prefix are suggested. We say string s1 has string s2 as a prefix if and only if the first |s2| characters of s1 are the same as s2 where |s2| is the length of s2.

These days Little Hi has been working on a way to improve the QAC performance. He collected N high-frequency queries. We say a string s is a proper prefix if there are no more than 5 collected queries have s as a prefix. A string s is a shortest proper prefix if s is a proper prefix and all the prefixes of s(except for s itself) are not proper prefixes. Little Hi wants to know the number of shortest proper prefixes given N collected queries.

Hint: the 4 shortest proper prefixes for Sample Input are "ab", "bb", "bc" and "be". Empty string "" is not counted as a proper prefix even if N <= 5.

输入

The first line contains N(N <= 10000), the number of collected queries.

The following N lines each contain a query.

Each query contains only lowercase letters 'a'-'z'.

The total length of all queries are no more than 2000000.

Input may contain identical queries. Count them separately when you calculate the number of queries that have some string as a prefix.

输出

Output the number of shortest proper prefixes.

样例输入
12aababcabcdeabcdeabcbabcdbcdebcbbdbcacbeebbb
样例输出
4
根据题目意思,把由相同字母开头的字符串看成一个集合,在每个集合里面找到符合要求的最短proper前缀串。proper就是要求这个集合里面以该字符串为前缀的数目不大于五个,这样就选出了很多prope前缀,在众多前缀字符串里再按照要求选出最短proper前缀,就是该字符串不含有任何其他proper前缀为前缀。
用tiretree做的话能够比较简单地完成题目要求。对于节点的结构,最好里面有个int变量tag保存从根到该节点为前缀的字符串数目,这个从建立树的时候每次经过该节点的话对改变量++就可以了。
建立好之后按照题意只需要从根节点开始找到第一个不大于5的节点就可以了。
#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAX 26#define LENGTH 2000001int cnt;typedef struct Node{      int tag;//以到这个节点为前缀的字符串数目      struct Node *next[MAX];}NODE;void insert_node(NODE *root,char *s1){    NODE *p=root;    int i;    char *s=s1;    if(root==NULL || *s1=='\0' )        return;    while( *s>='a'&& *s<='z')    {      if( (p->next)[*s-'a']==NULL )      {          NODE *temp=(NODE *)malloc(sizeof(NODE));          for(i=0;i<MAX;i++)          {              (temp->next)[i]=NULL;          }          (p->next)[*s-'a']=temp;           p=temp;           temp->tag=1;      }      else{        p=((p->next)[*s-'a']);        (p->tag)++;      }      s++;    }}int search(NODE *root){    NODE *p=root;    int i=0;    if(p==NULL)        return 0;    if( (p->tag)<=5 )    {    cnt++;    return 0;    }    for(i=0;i<MAX;i++)    {        if((p->next[i])!=NULL )        {         search(p->next[i]);        }    }    return 0;}void del(NODE *root){    int i;    for(i=0;i<MAX;i++)    {        if(root->next[i]!=NULL)        {            del(root->next[i]);        }    }    free(root);}int main(void){    int m,i;    char s[LENGTH];    while(scanf("%d",&m)!=EOF)    {        memset(s,0,sizeof(s));        NODE *root=NULL;        root=(NODE *)malloc(sizeof(NODE));        root->tag=MAX;        cnt=0;        for(i=0;i<MAX;i++)        {            (root->next)[i]=NULL;        }        getchar();        for(i=0;i<m;i++)        {            fgets(s,LENGTH,stdin);            insert_node(root,s);        }        search(root);        printf("%d\n",cnt);        del(root);     }    return 0;}

0 0