题意:可以翻转两个字符串的任一一部分,问有几种方式可以使得两个字符串相同,保证两个串不相等
思路:从左到右找到两个不相等的左端点L,从右往后找找到两个不相等的右端点R,先看L到R里面有满足的情况,两个串中必须满足的条件是将一个串颠倒过来等于另一个串才会有一种,否则输出0,然后看L左面和R右边的那一块,必须是对称的,遇到对称加1,否则跳出。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #include<algorithm> #include <map> m using namespace std; #define memset(a,b) memset(a,b,sizeof(a)) #define ll long long #define inf 0x3f3f3f3f const int maxn=1e5+10; char A[maxn]; char B[maxn]; int main() { scanf("%s %s",A,B); ll sum=0; int l=-1,r=-2; int len = strlen(A); for(int i=0; i<len; i++) { if(A[i] != B[i]) { l=i; break; } } for(int i=len-1; i>=0; i--) { if(A[i] != B[i]) { r=i; break; } } int flag=0; for(int i=l,j=r; i<=r&&j>=l; i++,j--) { if(A[i] != B[j]) { flag =1; break; } } if(flag == 1) printf("0\n"); else { sum=1; for(int i=l-1,j=r+1; i>=0&&j<len; i--,j++) { if(A[i] == B[j]) sum++; else break; } printf("%lld\n",sum); } return 0; }
题意:与上题不同的是两个字符串可以相等。
思路:上题是分了两种情况:(1)两个串完全不同(L 和R没有值)(2)L和R有变化
只需在加一种情况:两个串相等用Manacher找最长回文子序列就是答案。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #include<algorithm> #include <map> m using namespace std; #define memset(a,b) memset(a,b,sizeof(a)) #define ll long long #define inf 0x3f3f3f3f const int maxn=2e6+10; char A[maxn]; char B[maxn]; char ma[maxn*2]; int mp[maxn*2]; int la; void Manacher() { la=2; int len=strlen(B); ma[0]='$'; ma[1]='#'; for(int i=0; i<len; i++) { ma[la++]=B[i],ma[la++]='#'; } ma[la]=0; int id=0,mx=0; mp[0]=0; for(int i=0; i<la; i++) { mp[i]=mx>i?min(mp[2*id-i],mx-i):1; while(ma[i+mp[i]]==ma[i-mp[i]]) mp[i]++; if(i+mp[i] > mx) { mx=i+mp[i]; id = i; } } return ; } int main() { ll T; cin>>T; while(T--) { scanf("%s %s",A,B); ll sum=0; int l=-1,r=-2; int len = strlen(A); for(int i=0; i<len; i++) { if(A[i] != B[i]) { l=i; break; } } for(int i=len-1; i>=0; i--) { if(A[i] != B[i]) { r=i; break; } } if(strcmp(A,B)==0) { Manacher(); ll ans =0; for(int i=1; i<la; i++) ans+=mp[i]/2; printf("%lld\n",ans); continue; } int flag=0; for(int i=l,j=r; i<=r&&j>=l; i++,j--) { if(A[i] != B[j]) { flag =1; break; } } if(flag == 1) printf("0\n"); else { sum=1; for(int i=l-1,j=r+1; i>=0&&j<len; i--,j++) { if(A[i] == B[j]) sum++; else break; } printf("%lld\n",sum); } } return 0; }