57pts只wa一个点求调
查看原帖
57pts只wa一个点求调
927858
__Legends__楼主2025/8/4 19:04

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;
}
2025/8/4 19:04
加载中...