原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=830&page=show_problem&problem=396
题意: 如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串以k为周期。例
如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。
输入一个长度不超过80的字符串,输出其最小周期。
解题思路过程:
首先,我想到的是用队列
把待测串s[]的首字符s[0]入队,从第二个字符s[1]开始和队首元素对比,
if(s[i]==c.pop())(c为队列)队首出队;sum++;
else c.push(s[i])
一直到队列为空or所有元素都遍历过一遍为止。
最后如果sum==0 || 串的长度与sum取模!=0 就说明它的最短周期是它本身
1 #include <iostream> 2 #include<string> 3 #include<queue> 4 using namespace std; 5 int main(){ 6 int T; 7 cin>>T; 8 while(T){ 9 string a; 10 cin>>a; 11 int len=a.length(); 12 int lena=len; 13 len--; 14 queue<char>c; 15 c.push(a[0]); 16 int i=1,sum=0; 17 while(!c.empty()&&len){ 18 char temp=c.front(); 19 if(temp==a[i]){ 20 c.pop();sum++; 21 } 22 else c.push(a[i]); 23 i++;len--; 24 } 25 // if(sum==1)sum=lena; 26 if(sum==0)sum=lena; 27 else if((lena%sum)!=0)sum=lena; 28 cout<<sum<<endl; 29 T--; 30 } 31 return 0; 32 }
后来测试才发现,这算法有个致命的bug!!!
“算法盲点”:amanamanamanaman
按此串所模式,最小周期应该是4,但因为使用队列的缘故,无法实现出现队列为空的情况顾,此路不通。。。
经过重新观察数据规模,发现和题意,发现通过枚举完成此题。
1 #include <iostream> 2 #include<string> 3 #include<queue> 4 using namespace std; 5 int main(){ 6 int T; 7 cin>>T; 8 while(T){ 9 string a; 10 cin>>a; 11 int ok=1; 12 int len=a.length(); 13 for(int i=1;i<=len;i++){ 14 if(len%i==0){ 15 ok=1; 16 for(int j=i;j<len;j++){ 17 if(a[j]!=a[j%i]){ 18 ok=0; 19 break; 20 } 21 } 22 } 23 if(ok){cout<<i<<endl;break;} 24 } 25 T--; 26 } 27 return 0; 28 }
首先从1开始枚举子串长度,如果待测串%子串长度==0就可以接着去对照待测串中的元素最终找出待测串的最小周期