JZOJ 4910. 【NOIP2017模拟12.3】子串
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 4910. 【NOIP2017模拟12.3】子串
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
Input
Sample Input
4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
ba
ccc
Output
Sample Output
4
-1
4
3
Data Constraint
Solution
我們第一眼可以想到對于每一個串都使用KMP逐一匹配
那么時間復雜度將是 O(T?N2?S),明顯超限!
繼續思考,知道性質:對于三個串:a,b,c;
a是b的子串,b是c的子串;
那么a也會是c的子串!
于是我們想到優化,枚舉相鄰的兩個子串,判斷是否是子串
如果是,那么就不需要處理,繼續枚舉!
如果不是,那么就從下往上對于這個串進行一次逐一比對
再加上是否大于Ans的剪枝優化
時間復雜度可以接近 O(T?N?S),成功AC!
Code
#include<cstdio> #include<cstring> using namespace std; const int N=501,M=2002; int ans,n; int a[N],next[N][M]; char s[N][M]; inline int read() {int data=0; char ch=0;while(ch<'0' || ch>'9') ch=getchar();while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();return data; } inline void init() {n=read();ans=0;for(int i=1;i<=n;i++){scanf("%s",s[i]+1); a[i]=strlen(s[i]+1);for(int j=2,k=0;j<=a[i];j++){while(k && s[i][j]!=s[i][k+1]) k=next[i][k];if(s[i][j]==s[i][k+1]) k++;next[i][j]=k;}} }//KMP的預處理 inline void work() {for(int k=n;k>1 && k>ans;k--){bool bz=false;for(int i=1,j=0;i<=a[k];i++){while(j && s[k][i]!=s[k-1][j+1]) j=next[k-1][j];if(s[k][i]==s[k-1][j+1]) j++;if(j==a[k-1]){bz=true;break;}}//兩兩配對if(!bz){if(k>ans) ans=k;for(int p=n;p>k && p>ans;p--){bz=false;for(int i=1,j=0;i<=a[p];i++){while(j && s[p][i]!=s[k-1][j+1]) j=next[k-1][j];if(s[p][i]==s[k-1][j+1]) j++;if(j==a[k-1]){bz=true;break;}}if(!bz){if(p>ans) ans=p;break;}}//逐一配對}}if(!ans) printf("-1\n"); else printf("%d\n",ans); } int main() {int T=read();while(T--){init();work();}return 0; }總結
以上是生活随笔為你收集整理的JZOJ 4910. 【NOIP2017模拟12.3】子串的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 4909. 【NOIP2017
- 下一篇: JZOJ 4919. 【NOIP2017