题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012
题目描述
BaoBao has just found two strings and in his left pocket, where indicates the -th character in string , and indicates the -th character in string .
As BaoBao is bored, he decides to select a substring of and reverse it. Formally speaking, he can select two integers and such that and change the string to .
In how many ways can BaoBao change to using the above operation exactly once? Let be an operation which reverses the substring , and be an operation which reverses the substring . These two operations are considered different, if or .
Input
There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:
The first line contains a string , while the second line contains another string . Both strings are composed of lower-cased English letters.
It’s guaranteed that the sum of of all test cases will not exceed .
Output
For each test case output one line containing one integer, indicating the answer.
Sample Input
2
abcbcdcbd
abcdcbcbd
abc
abc
Sample Output
3
3
Hint
For the first sample test case, BaoBao can do one of the following three operations: (2, 8), (3, 7) or (4, 6).
For the second sample test case, BaoBao can do one of the following three operations: (1, 1), (2, 2) or (3, 3).
题目大意
输入两个长度相等字符串 ,将 中的一个子串翻转,使得反转后的 与 相同,求有几种翻转方法
解题思路
- 若 ,那么可以翻转的方法数就等于将= 串中所有的回文串的数目
- 若 不完全相同,那么从左往右找到第一个 不同的位置 ,从右往左找到第一个 不同的位置 ,如果 翻转后与 不同,那么不存在翻转方法,直接输出 ;如果 翻转后与 相同,那么以该子串往两边扩展,子串能扩展的最大长度就是可以翻转的方法数。
AC代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define io ios::sync_with_stdio(0),cin.tie(0)
#define ms(arr) memset(arr,0,sizeof(arr))
#define mc(a,b) memcpy(a,b,sizeof(b))
#define inf 0x3f3f3f
#define fin freopen("in.txt", "r", stdin)
#define fout freopen("out.txt", "w", stdout)
typedef long long ll;
typedef unsigned long long ULL;
const int mod=1e9+7;
const int N=2e6+7;
char s[N],t[N],s_new[N<<1];
int p[N<<1];
int n;
void init()
{
int len=strlen(s);
s_new[0]='$';
s_new[1]='#';
for(int i=0; i<len; i++)
{
s_new[i*2+2]=s[i];
s_new[i*2+3]='#';
}
s_new[2*len+2]='\0';
}
void manacher()
{
int len=strlen(s_new);
int id=-1;
int mx=0;
for(int i=1; i<len; i++)
{
if(i<mx) p[i]=min(p[id*2-i],mx-i);
else p[i]=1;
while(s_new[i+p[i]]==s_new[i-p[i]])
p[i]++;
if(mx<i+p[i])
{
mx=i+p[i];
id=i;
}
}
}
int main()
{
// fin;
scanf("%d",&n);
getchar();
while(n--)
{
s[0]='\0';
t[0]='\0';
scanf("%s",s);
scanf("%s",t);
int slen=strlen(s);
int i,j;
for(i=0;s[i]==t[i]&&i<slen;i++);
if(i==slen)
{
init();
manacher();
ll ans=0;
int len=strlen(s_new);
for(int k=1;k<len;k++) ans+=(ll)(p[k]/2);
printf("%lld\n",ans);
}
else{
for(j=slen-1;s[j]==t[j]&&j>=0;j--);
ll ans=1;
for(int k=0;k<=j-i;k++)
{
if(s[i+k]!=t[j-k])
{
ans=0;
break;
}
}
if(ans==0) printf("0\n");
else{
i--;j++;
while(i>=0&&j<slen&&s[i]==s[j])
{
ans++;
i--;j++;
}
printf("%lld\n",ans);
}
}
}
return 0;
}