Strings in the Pocket
作者:互联网
这题是今年浙江省的省赛k题
题目大意为 给你俩个字符串s和t 任意反转s的一个子串 求反转后让s和t相等的方法有多少
当s和t相等时 用马拉车算法求出回文子串的长度
当s和t不相等时 用模拟法求答案
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+100;
long long t,r[maxn*2];
char a[maxn],b[maxn],s[maxn*2];
long long change()
{
long long len=strlen(a);
long long j=2;
s[0]='$';
s[1]='#';
for(long long i=0; i<len; i++)
{
s[j++]=a[i];
s[j++]='#';
}
s[j++]='#';
return j;
}
long long manacher()
{
long long len=change(),maxn=1,mid=1,ans=0;
for(long long i=1; i<len; i++)
r[i]=0;
for(long long i=1; i<len; i++)
{
if(i<maxn) r[i]=min(maxn-i,r[2*mid-i]);
else r[i]=1;
while(s[i+r[i]]==s[i-r[i]]) r[i]++;
if(maxn<i+r[i])
{
maxn=i+r[i];
mid=i;
}
ans+=r[i]/2;//求回文子串的个数
}
return ans;
}
int main()
{
scanf("%lld",&t);
getchar();
while(t--)
{
scanf("%s",a);
scanf("%s",b);
if(strcmp(a,b)==0)
{
printf("%lld\n",manacher());
}
else
{
long long q=strlen(a),aa,bb;
for(long long i=0; i<q; i++)
{
if(a[i]!=b[i])
{
aa=i;
break;
}
}//从起点开始找a b不同时的下标
for(long long i=q-1; i>=0; i--)
{
if(a[i]!=b[i])
{
bb=i;
break;
}
}//从终点开始找a b不同时的下标
long long flag=0;
if(aa==bb)
{
printf("0\n");
continue;
}//表示a和b完全不相同 输出0
for(long long i=aa,j=bb; i<=bb,j>=aa; i++,j--)
{
if(a[i]!=b[j])
{
flag=1;
break;
}
}//找不同的地方是否可以反转后相等
long long ans=0;
if(flag==1) printf("0\n");//不可以 输出0
else//可以
{
for(long long i=aa-1,j=bb+1; i>=0,j<q; i--,j++)
{
if(a[i]==a[j])
{
ans++;//从中间向俩边发散 找回文串的个数
}
else break;
}
printf("%lld\n",ans+1);//输出
}
}
}
return 0;
}
标签:aa,相等,bb,long,Pocket,flag,maxn,Strings 来源: https://blog.csdn.net/tjndsg/article/details/89682524