1051 接龙游戏

1051 接龙游戏

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 Description

给出了N个单词,已经按长度排好了序。如果某单词i是某单词j的前缀,i->j算一次接龙(两个相同的单词不能算接龙)。

你的任务是:对于输入的单词,找出最长的龙。

输入描述 Input Description

第一行为N(1<=N<=105)。以下N行每行一个单词(由小写组成),已经按长度排序。(每个单词长度<50)

输出描述 Output Description

仅一个数,为最长的龙的长度。

样例输入 Sample Input

5

i

a

int

able

inter

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

1<=N<=105

分类标签 Tags 点此展开 

 
 
题解:字典树+dfs
AC代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 1000100
int n,tot,ans,ne,len;
int head[N],next[N],v[N];
bool w[N];
char s[90];
void dfs(int k,int p){
    if(p==len) return ;
    int x=s[p]-'a'+1,t=0;
    for(int i=head[k];i;i=next[i]) if(v[i]==x){t=i;break;}//寻找有没有x节点,如果有记录位置 
    if(!t){v[++ne]=x;t=ne;next[ne]=head[k];head[k]=ne;}//如果没有在字典树上建立一个节点 
    if(p==len-1){w[t]=1;tot++;ans=max(ans,tot);return ;}//扫到头,标记末尾,当前答案+1(自己也算一个),更新ans,退出 
    else if(w[t]) tot++;//有前缀出现过,当前答案+1 
    dfs(t,p+1);//从t节点再往下扫 
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        len=strlen(s);
        tot=0;//当前答案 从0开始寻找 
        dfs(0,0);//0号节点为根节点,从字符串的0号位置往后扫 
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2016-08-10 14:42  神犇(shenben)  阅读(274)  评论(0编辑  收藏  举报