接龙游戏
【题目描述】
给出了N个单词,已经按长度排好了序。如果某单词i是某单词j的前缀,i --> j算一次接龙(两个相同的单词不能算接龙)。
你的任务是对于输入的单词,找出最长的龙。
【输入描述】
第一行为N(1 <= N <= 10^5)。以下N行每行一个单词(由小写组成),已经按长度排序(每个单词长度<50)。
【输出描述】
仅一个数,为最长的龙的长度。
【样例输入】
5
i
a
int
able
inter
【样例输出】
3
字典序+栈模拟:
源代码: #include<iostream> #include<algorithm> //包含了【unique()】函数。 #include<cstring> //包含了【substr()】、【length()】函数。 #include<stack> using namespace std; int n,num(0),ans(0); string i[100001]; stack <string> h; bool Can(string s1,string s2) //判断。 { if (s1==s2||s1.length()>s2.length()) return false; return s1==s2.substr(0,s1.length()); //从s2[0]到s2[s1.length]的子串。 } void Make_can(string s) //努力试图加入此元素。 { while (h.size()&&!Can(h.top(),s)) { h.pop(); num--; } h.push(s); num++; } int main() { cin>>n; for (int a=1;a<=n;a++) cin>>i[a]; sort(i+1,i+n+1); //救人的字典序。 n=unique(i+1,i+n+1)-(i+1); //排序相邻去重,并返回整型末位置数字。 for (int a=1;a<=n;a++) if (h.empty()||Can(h.top(),i[a])) //队空就入,判断队头是否为i[a]的前缀。 { h.push(i[a]); //是就入队并更新答案。 ans=max(ans,++num); } else Make_can(i[a]); cout<<ans; return 0; }
Trie+DFS: