牛客15870 好位置 KMP/暴力循環

題目連接:牛客15870 好位置 KMP/循環 傳送門

題目描述

給出兩個串s和x
定義s中的某一位i爲好的位置,當且僅當存在s的子序列在這裏插入圖片描述
定義s中的某一位i爲好的位置,當且僅當存在s的子序列 滿足y=x且存在j使得i=kj成立。問s中是否所有的位置都是好的位置。

輸入描述

一行兩個字符串s,x,這兩個串均由小寫字母構成。 1 <= |s|, |x| <= 200000

輸出描述

Yes表示是。
No表示不是。

題解

兩個串s和x,就是s中的任意一個字符的左右連續字符都能和x匹配,匹配成功yes,不成功no。

方法1
KMP匹配並記錄匹配成功的位置,
通過匹配成功的次數和字符串y的長度可計算出匹配成功的長度總和,若總和小於字符串x則No
若匹配成功的位置差大於字符串y的長度,則No

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int MAX=1e6+7;
int nt[MAX];
vector<int>p;
void kmp_next(string str,int next[])
{
    int len=str.size();
    next[0]=-1;
    for(int i=0,j=-1;i<len;)
    {
        if(j==-1||str[i]==str[j])
        {
            next[++i]=++j;
        }
        else j=next[j];
    }
}
int kmp(string s,string str,int next[])
{
    int l1=s.size(),l2=str.size(),f=0;
    for(int i=0,j=0;i<l1&&j<l2;)
    {
        if(j==-1||s[i]==str[j])
        {
            i++,j++;
        }
        else 
            j=next[j];
        if(j==l2){
            j=next[j];
            p.push_back(i); 
        }
    }
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
    string s,str;
    cin>>s>>str;
    kmp_next(str,nt);
    kmp(s,str,nt);
    int f=0;
    if(p.size()*str.size()<s.size())f=1;
	for(int i=1;i<p.size();i++)
	{
		if(p[i]-p[i-1]>str.size()){
			f=1;break;
		}
	}
	if(f)cout<<"No";
	else cout<<"Yes";    
    return 0;
}

方法2
因爲符合條件的字符串x都是由字符串y組成,故可循環暴力匹配

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
    string s,str;
    cin>>s>>str;
    int l1=s.size(),l2=str.size(),f=0;
    for(int i=0;i<l1;i++)
    {
        if(s[i]!=str[i%l2]){
            f=1;break;
        }   
    }
    if(f)cout<<"No";
    else cout<<"Yes";
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章