洛谷题单 【算法2-4】字符串
P3375 【模板】KMP
https://www.luogu.com.cn/problem/P3375
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include<bits/stdc++.h> using namespace std; using u32 = unsigned; #define i128 __int128; using ll = long long;
using u64 = unsigned long long; const ll inf = 1e9; const ll INF = 1e18; const int N=1e6+10; int ne[N]; signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); string s1,s2; cin>>s1>>s2; int n=s1.size(),m=s2.size(); for(int i=1,j=0;i<m;i++) { while(j&&s2[i]!=s2[j])j=ne[j]; if(s2[i]==s2[j])j++; ne[i+1]=j; } for(int i=0,j=0;i<n;i++) { while(j&&s1[i]!=s2[j])j=ne[j]; if(s1[i]==s2[j])j++; if(j==m) { cout<<i-m+1+1<<'\n'; } } for(int i=1;i<=m;i++) { cout<<ne[i]<<" \n"[i==m]; }
return 0; }
|
P4391 [BOI2009] Radio Transmission 无线传输
https://www.luogu.com.cn/problem/P4391
所以推出:
1. 因为上下对应相等,故第1段等于红色段;
2. 因为是公共前后缀,故第2段等于第1段;
3. 因为上下对应相等,故第3段等于第2段;
4. 因为是公共前后缀,故第4段等于第3段;
5. ……
6. 红色段就是循环子串;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include<bits/stdc++.h> using namespace std; using u32 = unsigned; #define i128 __int128; using ll = long long;
using u64 = unsigned long long; const ll inf = 1e9; const ll INF = 1e18; const int N=1e6+10; int ne[N]; signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin>>n; string s; cin>>s; for(int i=1,j=0;i<n;i++) { while(j&&s[i]!=s[j])j=ne[j]; if(s[i]==s[j])j++; ne[i+1]=j; } cout<<n-ne[n]<<'\n';
return 0; }
|