YBTOJ:字符串题(KMP)
生活随笔
收集整理的這篇文章主要介紹了
YBTOJ:字符串题(KMP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 題目描述
- 解析
- 1.p[i]>0:
- 2.p[i]=0:
- 代碼
題目描述
解析
我個人做起來很費勁的一道題,用vector,并查集等等東西搞來搞去過掉了(竟然只WA了一次 )
看題解思路就一下子清晰了,還是對KMP的理解不到位。
現在看看題解的表演吧
首先容易想到,若設kmp的失配數組為p,則有:p[i]=i?pre[i]p[i]=i-pre[i]p[i]=i?pre[i]
現在問題就是如何利用失配數組逆推出字符串
因為字典序貪心顯然是正確的
所以我們可以從前往后推導
假設[1,i-1]的字符串都已求出,如何求出符合要求且字典序最小的第i位
回憶一下kmp匹配的流程:
可以分為兩種情況
1.p[i]>0:
此時通過上面的流程,可以發現:
s[i]=s[p[i]]s[i]=s[p[i]]s[i]=s[p[i]]
就很容易了
2.p[i]=0:
我們首先要明白p[i]=0是怎么得到的
因為kmp計算里的那個while語句始終成立,也就是s[i+1]!=s[j+1],導致j一直跳失配跳到了0
所以當前這一位只要和往前跳的那些不同就可以了
注意如果這個i不是第一位的話,它也應該是與第1位不同的
分析完上面兩種情況后,問題就變得很簡單啦
代碼
#include<bits/stdc++.h> using namespace std; #define ll long long typedef unsigned long long ull; const int N = 1e6+100; const int M=1e7+5; const int mod=1e9+7; int n,m; int l; int p[N]; char s[N];int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&m);p[i]=i-m;if(p[i]>0){s[i]=s[p[i]];}else{bool jd[28]={};int pl=p[i-1];while(pl){jd[s[pl+1]-'a'+1]=1;pl=p[pl];}if(i!=1) jd[1]=1;for(int j=1;j<=26;j++){if(!jd[j]){s[i]='a'+j-1;break;}}}}printf("%s",s+1);return 0; }總結
以上是生活随笔為你收集整理的YBTOJ:字符串题(KMP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是鹅蛋脸 鹅蛋脸是什么样子的
- 下一篇: YBTOJ:字符串匹配(KMP)