NOIP2017SummerTraining0705 T1 重復字符串
阿新 • • 發佈:2017-07-13
pla code aaaaa cde 字符串 整數 isp 沒有 main
題目描述
給定兩個字符串a和b,我們可以定義一些操作:a*b為將字符串a和字符串b連接起來,比如a= "aoe",b= "jkw",那麽a*b= "aoejkw"。進一步,我們可以有指數操作,a^0="", a^1=a, a^2=a*a, a^n=a*(a^(n-1))=a*a*…*a (n個a)
現在給你一個字符串,你可以將它看成是a^n的形式,比如字符串"abababab",可以認為是"abab"^2, 也可以是"abababab"^1,還可以是"ab"^4。
現在問題是,給定的字符串,我們想讓它變成a^n中的n達到最大,那麽這個n最大是多少?例如:"abababab"最大的n是4。
輸入
第一行,一個整數m,表示有m個字符串。
接下來m行每行輸入一個只含小寫字母的字符串。
輸出
輸出m行,對於每行輸出相應字符串的最大n。
樣例輸入
3 abcde aaaaaa abababab樣例輸出
1 6 4提示
30%的數據:字符串的長度≤1000;
100%的數據:字符串的長度≤1000000, m≤10,字符串內只含小寫字母。
看到這道題目後,我們先不要來想正解,我們來想暴力吧
暴力其實非常水啊
枚舉一個字符串,再枚舉這個長度,最後在比較一下是否全部符合就可以拿到30分啦啦啦,美滋滋
然後在比較字符串的時候有沒有覺得一個一個去比(字符串比較是逐位比較的)實在是太浪費了、
於是我們異想天開地想用數字去代替字符
好消息是這種方法是存在的哦
那就是Hash大法
我們可以使用Hash將字符串轉為數字,這樣比較就由O(N) 下滑為 O(1)啦,美滋滋
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 long long Mod1=1920454134; 10 long long A[1000005]; 11 char s1[1000005Show My Ugly Code]; 12 13 int main() 14 { 15 int _; 16 scanf("%d",&_); 17 while (_--) 18 { 19 scanf("%s",s1); 20 int Len=strlen(s1); 21 long long K=1; 22 for (int i=1; i<=Len; i++) 23 { 24 A[i]=((A[i-1] % Mod1) + (long long)(s1[i-1] - 97) * K % Mod1) % Mod1; 25 K=K * 26 % Mod1; 26 } 27 K=1; 28 for (int i=1; i<=Len; i++) 29 { 30 K=K * 26 % Mod1; 31 if (Len % i == 0) 32 { 33 long long Tmp=A[i]; 34 long long Sum=Tmp; 35 bool flag1=false; 36 for (int j=2; i*j <= Len; j++) 37 { 38 Sum=(Sum * K % Mod1 + Tmp) % Mod1; 39 if (Sum != A[i * j]) 40 { 41 flag1=true; 42 break; 43 } 44 } 45 if (! flag1) 46 { 47 printf("%d\n",Len / i); 48 break; 49 } 50 } 51 } 52 } 53 }
NOIP2017SummerTraining0705 T1 重復字符串