codevs 1051 接龙游戏
题目描述 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
/* 字典树(80分) 数组开大了超空间 小了RE...... 正解为单调栈 */ #include<iostream> #include<cstdio> #include<cstring> #include<map> #define maxn 1211110 #define maxx 110 using namespace std; int n,tot,ans; char s[maxx]; struct tree { map<int,int>next; bool w; }t[maxn]; void add() { int l=strlen(s),i,j,k,flag=0,len=0; int now=0; for(i=0;i<=l-1;i++) { int x=s[i]-'a'+1; if(t[now].next[x]) { now=t[now].next[x]; if(t[now].w)len++; } else { tot++; t[now].next[x]=tot; now=tot; } } if(!t[now].w)len++; t[now].w=1; ans=max(ans,len); } int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>s; add(); } printf("%d\n",ans); return 0; }
/* 正解为单调栈 维护一个栈,让栈中的元素都满足 前一个是后一个的前缀 栈的最大长度即为答案 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stack> #define maxn 100010 using namespace std; string s[maxn]; stack<int>t; int n,ans=1; int main() { int i,j,k; cin>>n; for(i=1;i<=n;i++) cin>>s[i]; sort(s+1,s+n+1); t.push(1); for(i=2;i<=n;i++) { while(!t.empty()) { int flag=0; int p=t.top(); string s1=s[i]; string s2=s[p]; int l1=s1.length(); int l2=s2.length(); if(l1>l2) { flag=1; for(j=0;j<=l2-1;j++) if(s1[j]!=s2[j]) { flag=0; break; } } if(flag)break; t.pop(); } t.push(i); if(t.size()>ans) ans=t.size(); } printf("%d\n",ans); return 0; }