【kmp】似乎在梦中见过的样子
生活随笔
收集整理的這篇文章主要介紹了
【kmp】似乎在梦中见过的样子
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
參考博客:
BZOJ 3620: 似乎在夢中見過的樣子?
?
【KMP】似乎在夢中見過的樣子
題目描述
「Madoka,不要相信QB!」伴隨著Homura的失望地喊叫,Madoka與QB簽訂了契約。這是Modoka的一個噩夢,也同時是上個輪回中所發生的事。為了使這一次Madoka不再與QB簽訂契約,Homura決定在剛到學校的第一天就解決QB。然而,QB也是有許多替身的(但在第八話中的劇情顯示它也有可能是無限重生的),不過,意志堅定的Homura是不會放棄的——她決定消滅所有可能是QB的東西。現在,她已感受到附近的狀態,并且把它轉化為一個長度為n的字符串交給了學OI的你。
現在你從她的話中知道,所有形似于A+B+A的字串都是QB或它的替身,且∣A∣≥k,∣B∣≥1(位置不同其他性質相同的子串算不同子串,位置相同但拆分不同的子串算同一子串),然后你必須盡快告訴Homura這個答案——QB以及它的替身的數量。
注:對于一個字符串S,|S|表示S的長度。
輸入
第一行一個字符串S,第二行一個數k。輸出
僅一行一個數ans,表示QB以及它的替身的數量。樣例輸入
aaaaa 1樣例輸出
6提示
對于全部數據,1≤∣S∣≤1.5×104,1≤k≤100,且字符集為所有小寫字母。
?
?
【題解】
就在參考博客里面了。
主要是自己不要意思把別人畫的圖復制過來。
枚舉所有左端點然后進行向右看看有沒有一個最長前綴是符合要求的。
?就是這么一個想法,但是細節稍微有點多。因為兩層for需要更細心。
?
【代碼】:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 const int N = 1e5+10; 7 8 char s[N]; 9 int k,n,ans; 10 int Next[N]; 11 int main() 12 { 13 scanf("%s%d",s+1,&k); 14 n = strlen( s+1 ); 15 16 //printf("%s %d %d\n",s+1,k,n); 17 //枚舉所有合法的左端點,左端點 預留2*k的距離 18 for(int L=1; L<= n-(k*2) ; L++ ) { 19 20 for(int i = 1 ; i <= L ; i++ ) Next[i] = L-1 ; 21 22 //提前預處理好Next數組 23 for(int i=L+1,j=L-1;i<=n;i++){ 24 while( j != L-1 && s[i] != s[j+1] ) j=Next[j]; 25 if( s[i] == s[j+1] ) j++ ; 26 Next[i] = j ; 27 } 28 29 for(int i=L+1,j=L-1;i<=n;i++){ 30 while( j != L-1 && s[i] != s[j+1] ) j=Next[j]; 31 if( s[i] == s[j+1] ) j++ ; 32 33 //預處理的Next派上用場了 34 //當最長前綴的兩倍 > 當前串(右端點-左端點)的長度 35 //利用Next數組縮短距離 36 while( (j-L+1)*2 >= (i-L+1) ) j = Next[j] ; 37 38 //符合題意 累加答案,即前綴長度大于k 39 if( j-L+1 >= k ) ans ++ ; 40 } 41 42 } 43 printf("%d\n",ans); 44 return 0; 45 } View Code?
轉載于:https://www.cnblogs.com/Osea/p/11333262.html
總結
以上是生活随笔為你收集整理的【kmp】似乎在梦中见过的样子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器人抓取 三维重建机器人抓取
- 下一篇: Pdf.js body.getReade