接龙游戏

【题目描述】

给出了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:

原文地址:https://www.cnblogs.com/Ackermann/p/5756588.html