题目大意就是给一个串,求他的"最小正周期",比如 abcabcabcabc 以3为周期,但同时6和12也是他的周期,但其中最小的周期为3,需要找到这个最小正周期。需要注意的是如 abcdef 这种看起来没有周期的串,实际上他的周期就是他本身的长度为6。更需要注意的是题目中的格式要求“Two consecutive output are separated by a blank line.”(因此而PE6次的我默默的流下了眼泪....)
解决方法可以如其他博客中谈到的采取模的方法,也可以采用string类中的截取子串方法来进行比较,如果以某个长度截取的子串比较到原串的最后都是相等的,那这个长度就为它的其中一个周期。如何找到最小的周期呢?那就从长度为1开始找就好了。代码如下:
#include <iostream> #include <string> #include <cstdio> #include <cstring> using namespace std ; int main(){ int t ; cin >> t ; while ( t -- ){ string str ; cin >> str ; int len = 1 ; ///截取子串长度变量 bool flag = true ; ///判断周期为串长度的情况 while ( len <= str.size() / 2 ){ ///因为周期能被串的长度整除,而超过一半长度的周期无法被串长度整除,所以只需要截取到一半的串长度就好了 bool check = true ; ///判断周期不是串长度的情况 string str2 = str.substr(0 , len) ; // cout << "str2 = " << str2 << endl ; for ( int i = len ; i < str.size() ; i += len ){ string str3 = str.substr(i , len) ; // cout << "str3 = " << str3 << endl ; if ( str2 != str3 ){ check = false ; break ; } } if ( len == str.size() / 2 && check == false ){ ///若此时len为串长的一半并且在此之前check均没有被判断成功,则此时修改flag变量 flag = check ; } if ( check ){ break ; } // cout << str2 << endl ; len ++ ; } if ( !flag ) cout << str.size() << endl ; else cout << len << endl ; if ( t ) ///一定注意格式控制 putchar('\n') ; } return 0 ; }