1. 程式人生 > >NOIP2017SummerTraining0705 T1 重復字符串

NOIP2017SummerTraining0705 T1 重復字符串

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[1000005
]; 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 }
Show My Ugly Code

NOIP2017SummerTraining0705 T1 重復字符串