Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
其实这题完全用不着字典树……看Discuss区里的哥们儿都在说字典树,Tries树什么的,把学概B的兄弟吓得够呛。其实这道题大可不必如此费事,简单的比较就能搞定。给初学C++的兄弟们提供个思路: 基本思路:先给字符串排序,之后对于每个字符串,分别和上下两个字符串比较(如果有的话),找到第一个字符不同,或者字符串终止的位置记录下来,则两个位置中比较靠后的,就是最短前缀串的位置。 这样比较只需对相邻两字符串比较一次,算法复杂度为O(n),已经非常好了 输出的时候注意:不要把'\0'也输出去,会WA的! 这是我的代码,仅供参考: Source: < C++ Memory: 240K Time: 0ms> #include<iostream> #include<cstring> #include<algorithm> //排序提速用的,为了0ms不惜一切代价 using namespace std; const int MAX = 1001; //要稍微开大一点,防止输入数据中有空行 struct Prefix{ char ch[24]; //字串,24个长度,也是适当的冗余 int PrefixPosition; //最短前缀位置 }str[MAX]; Prefix* pointer[MAX] = {NULL}; //用指针数组操作,排序时只交换指针 //不影响原来的字符串先后顺序 bool cmp(Prefix*a,Prefix*b){ //要返回bool类型,int不行 return strcmp(a->ch,b->ch) < 0; } int main(){ int count = 0,pos1 = 0,pos2 = 0; while(cin>>str[count].ch){ pointer[count] = &str[count]; ++count; } //sort the strings pointer in alphabetical order sort(pointer,pointer+count,cmp); //Compare for(int i = 0;i < count;++i){ //和前后比较 if(i > 0)pos1 = pos2; //这样可减少一半的重复 pos2 = 0; if(i < count - 1)while(pointer[i]->ch[pos2] && pointer[i]->ch[pos2] == pointer[i+1]->ch[pos2])++pos2; //用最大的 pointer[i]->PrefixPosition = max(pos1,pos2); } for(int i = 0;i < count;++i){ printf("%s ",str[i].ch); for(int j = 0;j <= str[i].PrefixPosition;++j) //不要把'\0'打进去 if(str[i].ch[j])putchar(str[i].ch[j]); printf("\n"); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator