给出了N个单词,已经按长度排好了序。如果某单词i是某单词j的前缀,i->j算一次接龙(两个相同的单词不能算接龙)。
你的任务是:对于输入的单词,找出最长的龙。
第一行为N(1<=N<=105)。以下N行每行一个单词(由小写组成),已经按长度排序。(每个单词长度<50)
仅一个数,为最长的龙的长度。
5
i
a
int
able
inter
3
1<=N<=105
/* 作者:NowAndForever 题目:p1051 接龙游戏 */ #include<cstdio> #include<stack> #include<string> #include<vector> #include<algorithm> using namespace std; bool pd(string a,string b)//判断字符串b是不是字符串a的子串 { int l=a.size(),i; int p=b.size(); if(l<=p)return 0;//如果a的长度小于等于b 跳出(相同的单词也不行) for(i=0;i<p;i++)//判断如果在b的范围内有不相同的情况就跳出 { if(a[i]!=b[i]) return 0; } return 1; } int main()//这就启发我们将所有单词按字典序排序,这样就使得前缀相同的单词被“挤”在一起了 { int n,i; char s[55]; scanf("%d",&n); vector<string>input;//便于保存字符串和排序 for(i=0;i<n;i++) { scanf("%s",s); input.push_back(s); } sort(input.begin(),input.end());//默认从小到大 stack<string>map;//定义一个字符串栈 int ret=0; for(i=0;i<n;i++) { //然后我们维护一个栈,枚举所有的字符串(按字典序排好的) 如果当前的字符串能和栈顶的字符串接龙的话 while(!map.empty()&&(!pd(input[i],map.top()))) //那么当前字符串入栈,继续枚举下一个字符串,如果不能接龙,那么栈顶字符串弹出, //当前字符串继续与弹出后的栈顶字符串比较,直到当前字符串与栈顶字符串能接成龙,然后当前字符串入栈, map.pop(); map.push(input[i]); if(map.size()>ret)//在这期间统计栈最多有多少个元素 ret=map.size(); } printf("%d\n",ret); return 0; }
原文:http://blog.csdn.net/u012773338/article/details/40189429