poj3693:maximum repetition substring
題意:給定乙個字串,求重複次數最多的連續重複子串。
思路:先窮舉長度l,然後求長度為l的子串最多能連續出現幾次。首先連續出現1次是肯定可以的,所以這裡只考慮至少2次的情況。假設在原字串中連續出現2次,記這個子字串為s,那麼s肯定包括了字元r[0], r[l], r[l*2],r[l*3], ……中的某相鄰的兩個。所以只須看字元r[l*i]和r[l*(i+1)]往前和往後各能匹配到多遠,記這個總長度為k,那麼這裡連續出現k/l+1次。最後看最大值是多少。但是l,l*2,l*3這些位置不一定是所求段的起始位置,於是我們可以再計算k對於長度l「多餘」出來的長度,看它和現在的起始位置之前的能不能「拼起來」與模式段匹配使重複的次數+1。
/*
** 倍增演算法(n*logn)
* 待排序陣列長度為n,放在0~n-1中,在最後補0
* sa為字尾陣列,把字尾從小到大排序把字尾開頭存起來,rank為名次陣列,以i開頭的字尾在所有字尾中排第幾
* sa的有效值為1~n,sa[0]必為n無效
* rank的有效值為0~n-1,rank[n]必為0無效
* height的有效值為2~n,前兩個為0**/
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=1e6+10;
int x[maxn];
int wa[maxn],wb[maxn],ww[maxn],wv[maxn],nn,z=1;
char str[100010];
int cmp(int *r,int a,int b,int l)
void da(int *r,int *sa,int n,int m)//求的陣列,得到的字尾陣列,最長長度+1,陣列裡的最大值(一般180或者255);
return ;
}int h[maxn];//也就是排名相鄰的兩個字尾的最長公共字首sa[i]和sa[i-1]
int rank[maxn];//名次陣列
void get_height(int *r,int *sa,int n)//同上,n小1
int rmq[maxn],mm[maxn],best[20][maxn];
void initrmq(int n)//初始化rmq
}int askrmq(int a,int b)
int a[maxn];
int sa[maxn],r[maxn];
//int judge(int mid)//分組
//// else//重新分組
//
// if(ans>=k)//次數超過了,那麼這個k長度下是可行的
// return 1;
// }
// return 0;
//}int solve(int n)
if(m>max)//更新m和答案
else
if(m==max)//次數相同的存起來}}
int start,flag=0;
for(int i=1;i<=n;i++)}}
printf("case %d: ",z++);//輸出答案
for(int i=0;iprintf("%c",str[start+i]);
printf("\n");
}int main()
}
求陣列中重複次數最多的元素
例如 陣列a 元素2 3 7 8各出現1次,1出現兩次,5出現4次,則重複次數最多的元素為5.定義乙個陣列int cnt max 將其元素全部初始化為0。然後遍歷陣列a,執行cnt a i 操作。最後在cnt陣列中找最大的數,對應的數即為重複次數最多的數。示例如下 以空間換時間,索引法 int ma...
C 找出陣列中重複次數最多的數值
給定乙個int陣列,裡面存在重複的數值,如何找到重複次數最多的數值呢?這是在某社群上有人提出的問題,我想到的解決方法是分組。1 先對陣列中的所有元素進行分組,那麼,重複的數值肯定會被放到一組中 2 將分組進行排序,排序條件是分組中的元素個數 3 元素數量最多的那個分組中的數值就是重複次數最多的。基於...
POJ 3693 (重複次數最多連續重複子串)
上邊寫了個大致思路,然後看了kuangbin的部落格,深入的了解了一下怎麼做。只是還得注意一些地方 設目前詢問的長度為k,則答案顯然為k l 1,但這不一定是最好的。拿一組例子來說 xbcabcab 因為要達到n logn的複雜度,所以外迴圈模擬長度,內迴圈模擬從第幾個位置開始,但每次加的都是l 所...