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; }