只能交换两个字符的一次,设成功匹配子串的字数为n
n>2时,No
n=2时,交换第一个子串的第一字母和第二子串的第二字母即可
n=1或n=0时,原理差不多,一个一个尝试交换后每次都进行kmp匹配寻找子串个数,
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6+7;
int nt[MAX];
int a=0,b=0;
void kmp_next(string pattern,int next[])
{
int len=pattern.size();
next[0]=-1;
for(int i=0,j=-1;i<len;)
{
if(j==-1||pattern[i]==pattern[j])
{
next[++i]=++j;
}
else
j=next[j];
}
}
int kmp(string s,string pattern,int next[])
{
int ls=s.size(),lp=pattern.size(),flag=0;
for(int i=0,j=0;i<ls;)
{
if(j==-1||s[i]==pattern[j]){
i++,j++;
}
else j=next[j];
if(j==lp){
flag++;
j=0;
if(flag==1)a=i-lp;
else if(flag==2)b=i-lp;
}
}
return flag;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
string s,pattern="suqingnianloveskirito";
cin>>s;
if(s.size()<pattern.size()){
cout<<"Yes"<<endl;
cout<<1<<" "<<2;
return 0;
}
else{
kmp_next(pattern,nt);
int n=kmp(s,pattern,nt);
if(n>2){
cout<<"No";
return 0;
}
else if(n==2){
cout<<"Yes"<<endl;
cout<<a+1<<" "<<b+2;
return 0;
}
else if(n==1){
int f=0;
for(int i=a;i<a+pattern.size();i++)
{
for(int j=0;j<s.size();j++)
{
if(i!=j&&s[i]!=s[j])
{
swap(s[i],s[j]);
if(kmp(s,pattern,nt)==0){
cout<<"Yes"<<endl;
cout<<i+1<<" "<<j+1;
return 0;
}
else swap(s[i],s[j]);
}
}
}
cout<<"No";
}
else {
int f=0;
for(int i=0;i<s.size();i++)
{
for(int j=i+1;j<s.size();j++)
{
if(s[i]!=s[j])
{
swap(s[i],s[j]);
if(kmp(s,pattern,nt)==0){
cout<<"Yes"<<endl;
cout<<i+1<<" "<<j+1;
return 0;
}
else swap(s[i],s[j]);
}
}
}
cout<<"No";
}
}
return 0;
}
京公网安备 11010502036488号