其他分享
首页 > 其他分享> > Strings in the Pocket

Strings in the Pocket

作者:互联网

题目链接 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