码迷,mamicode.com
首页 > 其他好文 > 详细

codevs1051

时间:2015-07-22 13:09:24      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

题目地址:http://codevs.cn/problem/1051/

分析:

——题目难度:提高一等

1、数据结构(Data Structure):①Hash(用map或人工)②Stack(栈)

2、算法(Algorithm): DP 穷举

3、题目简述:

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

 

4、算法描述:

算法①:

这题我第一感觉是DP,和打导弹(拦截导弹)那题大同小异,但是n的范围伤不起 最大100000

时间复杂度:O(n^2)

空间复杂度:O(n)

很明显不行 

算法②:

其实依照题目中这种接龙的方式,我们很容易就想到枚举的算法。比如有一个单词tihs,我们先枚举tih,再枚举ti,再枚举t , 枚举他们是不是在前面出现过(题目说了单词按长度排序,至于为什么倒过来而不是先t再ti再tih ,是因为这样第一次找到的一定是最长的那个,直接修改了break就可以了,判断是否出现过就用哈希表了)

这样的算法明显比算法①快,但还是有压力的

时间复杂度:哈希表我用的map实现(偷懒- -) map查找和插入都是O(log n)

   一共是N个单词,每个单词要查找k次,插入1次

   总时间复杂度O(n * k * log n + n * log n),

PS:咳咳,仅供参考啊 参考 参考

空间复杂度: O(n) 只要有Hash就可以了 Map是动态扩展

这样看,空间上没有问题,但时间上还是很危险,在OJ上这个算法我拿了80分,2个点接近2.4秒,很恐怖

算法③:

这个算法有一些技巧,但也不难想到,为什么这么说呢?

其实只要你是一个玩过接龙游戏的人看这个题目的时候就会发现这个规则十分的特别,平常的接龙游戏是后缀接前缀,而本题的规则很特殊,前缀才是接龙

这就启发我们将所有单词按字典序排序,这样就使得前缀相同的单词被“挤”在一起了

然后我们维护一个栈,枚举所有的字符串(按字典序排好的) 如果当前的字符串能和栈顶的字符串接龙的话,那么当前字符串入栈,继续枚举下一个字符串,如果不能接龙,那么栈顶字符串弹出,当前字符串继续与弹出后的栈顶字符串比较,直到当前字符串与栈顶字符串能接成龙,然后当前字符串入栈,在这期间统计栈最多有多少个元素

5、总结

本题主要在于如何巧妙地理解并运用题目中接龙的规则, 然后合理使用栈这一数据结构  


代码:

#include <string>
#include <algorithm>
#include <iostream>
#include <stack>
using namespace std;

typedef struct data{
string s;
}data;

bool cmp(data x,data y)
{
int len = x.s.length() < y.s.length() ? x.s.length(): y.s.length();
for(int i = 0; i < len; i++)
{
if(x.s[i] < y.s[i])
return true;
else if(x.s[i] > y.s[i])
return false;
}
if(x.s.length() < y.s.length())
return true;
else return false;
}
data ch[100007];

int main()
{
int n;
cin>>n;
for(int i = 0; i < n; i++)
cin>>ch[i].s;

sort(ch,ch+n,cmp);
stack<data> mystatck;
int max = 1;
mystatck.push(ch[0]);
data tmp;
for(int i = 1; i < n; i++)
{
tmp = mystatck.top();
if(ch[i].s.find(tmp.s,0) == 0)
{
if(tmp.s.length() != ch[i].s.length())
mystatck.push(ch[i]);
}
else
{
while( !mystatck.empty()){
tmp = mystatck.top();
if(ch[i].s.find(tmp.s,0) == 0)
break;
mystatck.pop();
}
mystatck.push(ch[i]);
}
max = max > mystatck.size() ? max : mystatck.size();
// cout<<mystatck.size()<<endl;
}
cout<<max<<endl;
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

codevs1051

标签:

原文地址:http://blog.csdn.net/boyxiejunboy/article/details/47000779

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!