rt,求各位大佬帮调,思路就是先用哈希,然后考虑倒着模拟整个过程,具体实现请看代码
dfs中保证L1最长,L2次长,L3最短
a,b,c用来表示L1,L2,L3分别是最开始的a,b,c中哪个位置
chk函数是用来判断能否拼接的
cnt就是用来判断字符串中是否只存在两种字母的
sub4只wa#13,红温了
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int L=1e7+5;
const int base=2333;
int T,n;
bool ok;
char s[L];
ull Pow[L],h[L];
ull calc(int l,int r){
return h[r]-h[l-1]*Pow[r-l+1];
}
bool chk(int l1,int L1,int l2,int L2,int l3,int L3){
ull u1=calc(L1,L1+l1-1),u2=calc(L2,L2+l2-1),u3=calc(L3,L3+l3-1);
if(u1==u2+Pow[l2]*u3) return true;
if(u1==u3+Pow[l3]*u2) return true;
return false;
}
void dfs(int l1,int L1,int l2,int L2,int l3,int L3,int a,int b,int c){
// cout<<l1<<' '<<l2<<' '<<l3<<'\n';
if(!chk(l1,L1,l2,L2,l3,L3)) return;
if(l1==2&&l2==1&&l3==1){
if('a'+b==s[L2]&&'a'+c==s[L3]) return (void)(ok=true);
else return;
}
if(l2==l3) return;
if(chk(l2,L2,l3,L3,l2-l3,L2+l3)){
if(l3>=l2-l3) dfs(l2,L2,l3,L3,l2-l3,L2+l3,b,c,a);
else dfs(l2,L2,l2-l3,L2+l3,l3,L3,b,a,c);
}
else if(chk(l2,L2,l2-l3,L2,l3,L3)){
if(l2-l3>=l3) dfs(l2,L2,l2-l3,L2,l3,L3,b,a,c);
else dfs(l2,L2,l3,L3,l2-l3,L2,b,c,a);
}
}
int main(){
scanf("%d",&T);
while(T--){
ok=false;
scanf("%s",s+1);
int l1=strlen(s+1);
scanf("%s",s+l1+1);
int l2=strlen(s+l1+1);
scanf("%s",s+l1+l2+1);
int l3=strlen(s+l1+l2+1);
Pow[0]=1;
int cnt=0;
for(int i=1;i<=l1+l2+l3;i++) Pow[i]=Pow[i-1]*base,cnt|=(1<<(s[i]-'a'));
for(int i=1;i<=l1+l2+l3;i++) h[i]=h[i-1]*base+(s[i]-'a');
int L1=1,L2=l1+1,L3=l1+l2+1,p[4]={-1,0,1,2};
if(l2>l1) swap(l1,l2),swap(L1,L2),swap(p[1],p[2]);
if(l3>l1) swap(l1,l3),swap(L1,L3),swap(p[1],p[3]);
if(l3>l2) swap(l2,l3),swap(L2,L3),swap(p[2],p[3]);
dfs(l1,L1,l2,L2,l3,L3,p[1],p[2],p[3]);
// cout<<cnt<<'\n';
if(l1==1&&l2==1&&l3==1&&s[1]=='a'&&s[2]=='b'&&s[3]=='c') puts("YES");
else if(ok&&(cnt==3||cnt==5||cnt==6)) puts("YES");
else puts("NO");
}
return 0;
}