HDU 5510
Posted tiberius
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5510相关的知识,希望对你有一定的参考价值。
题意略。
思路:
这算是个铜牌题吧。思路是kmp+栈(类似于单调栈的那种想法),每个字符串进栈说明当前的栈是空栈,或者说该字符串在与栈顶元素比较时,
碰到了之前的不是它字串的字符串。
我们从前往后遍历这些字符串,
如果栈顶字符串是它的字串,那么我就弹出栈顶元素,继续比较。
如果栈顶字符串不是它的字符串,那么我就将当前字符串压入栈,并记录当前字符串标号。
有几个优化:
1.预先把字符串长度计算出来,如果栈顶字符串比当前字符串长,那么我们可以肯定,栈顶字符串不是当前字符串的字串。
2.预先把所有字符串的kmpNext数组处理好。
每个字符串进栈一次,出栈一次,总复杂度200 * 500 * 2。
代码附上:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn0 = 505; 4 const int maxn1 = 2005; 5 6 int len[maxn0],stk[maxn0],kmpNext[maxn0][maxn1],t,n,tp; 7 char str[maxn0][maxn1]; 8 9 void preKMP(char mode[],int m) 10 int i = 0,j = kmpNext[m][0] = -1; 11 while(mode[i]) 12 while(j != -1 && mode[j] != mode[i]) j = kmpNext[m][j]; 13 if(mode[++j] == mode[++i]) kmpNext[m][i] = kmpNext[m][j]; 14 else kmpNext[m][i] = j; 15 16 17 int kmp(char mode[],char str[],int m) 18 int ret = 0; 19 int i = 0,j = 0; 20 while(str[i]) 21 while(j != -1 && mode[j] != str[i]) j = kmpNext[m][j]; 22 ++i;++j; 23 if(!mode[j]) 24 ++ret; 25 break; 26 27 28 return ret; 29 30 31 int main() 32 scanf("%d",&t); 33 int cas = 1; 34 while(t--) 35 tp = 0; 36 scanf("%d",&n); 37 for(int i = 0;i < n;++i) 38 scanf("%s",str[i]); 39 preKMP(str[i],i); 40 len[i] = strlen(str[i]); 41 42 43 int lastest = -1; 44 stk[tp++] = 0; 45 for(int i = 1;i < n;++i) 46 if(len[tp - 1] > len[i]) 47 stk[tp++] = i; 48 lastest = i; 49 continue; 50 51 52 while(tp > 0 && kmp(str[stk[tp - 1]],str[i],stk[tp - 1]) > 0) --tp; 53 if(tp > 0) lastest = i; 54 stk[tp++] = i; 55 56 printf("Case #%d: %d\n",cas++,lastest == -1 ? -1 : lastest + 1); 57 58 return 0; 59
以上是关于HDU 5510的主要内容,如果未能解决你的问题,请参考以下文章