1051 接龙游戏
题目连接
http://www.wikioi.com/problem/1051/
题意:给你n个字符串(1<=n<=10^5),查找最长的接龙数,能够接龙的条件是:前一个串是本串的前缀,例如 a --->ab这样就算接龙,但是这里串相同不算接龙,例如
a---->aaa----aaa 这样的接龙长度算2,然后输出这些串最长能够得到的接龙,输出这个数就ok了;
一开始看到这题的时候,因为这里的接龙条件是前一个串是后一个串的前缀,就想到了使用字典树来做,因为使用每一个单词了建立字典树,将下一个单词添加进树时,能够得到之前单词,如果之前的单词是这个单词的前缀,这个单词在进行添加进字典树的时候,一定会进过这条路径。
然后解决这个问题使用的方法是:标记每个单词,当下一个单词经过了这个条路径,得到当前的这个标记,然后本单词在这个基础上加1,在这里要注意重复单词的出现。
然后记录其中最大的标记数。最后输出这个max
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef struct data{
int t;
data *next[26];
data()
{
t = 0;
for(int i = 0;i < 26; i++)
next[i]= NULL;
}
}data;
data *head;
int add(char *ch)
{
if(head == NULL)
head = new data();
data *p = head;
int t = 0;
int tmp;
bool flag = true;
for(int i = 0; i < strlen(ch); i++)
{
flag = true;
tmp = ch[i] -'a';
if(p->next[tmp] == NULL)
p->next[tmp] = new data();
else
{
t = t > p->next[tmp]->t ? t : p->next[tmp]->t;
flag = false;
}
p = p->next[tmp];
}
if(flag)
p->t = ++t;
return p->t;
}
void print(data *p)
{
for(int i = 0; i < 26; i++)
{
if(p->next[i] != NULL)
{
printf("%c %d\n",i+'a',p->next[i]->t);
print(p->next[i]);
}
}
}
int main()
{
int n;
scanf("%d",&n);
char ch[55];
int max = 0;
while(n--)
{
scanf("%s",ch);
int t = add(ch);
max = max > t ? max : t;
}
// print(head);
printf("%d\n",max);
return 0;
}
本代码在wikioi中得分80,内存超了,这个10^5个单词在创建字典树时内存消耗太大。。。。。纠结啊----------------------------
后来看了一下有人发的解题报告:
思路是,首先将这些单词进行字典序排序,然后使用一个栈来保存这个接龙,这个字典序排序貌似有两种排序,不知道是不是,但是在这里使用的排序方法是:
比较单词的每一个位置,字典序小的返回true,大的返回false,当有一个单词比较完后还没有结果,则长度短者返回true 长者false
自定义排序代码
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;
}
这样排序后前缀相同的单词都紧挨着了,然后使用栈来保存这个接龙,当单词将要入栈时,栈顶单词是该单词的前缀则进栈,不是则一直从栈中寻找,直到满足条件或是这个栈为空了,然后将这个单词入栈,在处理入栈的同时记录最长的接龙数。最后输出这个max就是答案,但是栈中保存的数据不一定是这个最长接龙的单词,这里已没有要求得到这个接龙。所以这里就不用考虑了。嘻嘻解决-----OK
代码:
#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;
}

浙公网安备 33010602011771号