主要算法来自于杨弋的论文
1,原始暴力代码,直接TLE
#include <iostream> #include <cstdio> #include <cstring> #define LMT 3003 using namespace std; //方法有问题,TLE char str1[LMT],str2[LMT]; int stack[LMT],len1[LMT],len2[LMT],con1[LMT],con2[LMT],tree1[LMT][LMT], tree2[LMT][LMT]; bool vis[LMT]; void dfs1(int u) { con1[u]=1; for(int i=0;i<len1[u];i++) { dfs1(tree1[u][i]); con1[u]+=con1[tree1[u][i]]; } } void dfs2(int u) { con2[u]=1; for(int i=0;i<len2[u];i++) { dfs2(tree2[u][i]); con2[u]+=con2[tree2[u][i]]; } } void kill(int u) { for(int i=0;i<len2[u];i++) vis[tree2[u][i]]=0; } void build(char str[],int len[],bool t) { int top=0,u=0,all=1; memset(len,0,sizeof(len)); for(int i=0;str[i];i++) switch(str[i]) { case '0': if(!t) tree1[u][len[u]++]=all; else tree2[u][len[u]++]=all; stack[top++]=u; u=all++; break; case '1':u=stack[--top];break; } if(!t) dfs1(0); else dfs2(0); } bool compare(int a,int b) { if(len1[a]!=len2[b]||con1[a]!=con2[b]) return 0; for(int i=0,j;i<len1[a];i++) { int x=tree1[a][i],y; for( j=0;j<len2[b];j++) if(0==vis[tree2[b][j]]) { y=tree2[b][j]; if(compare(x,y)) { vis[y]=1; break; } else kill(y); } if(j>=len2[b]) { kill(b); return 0; } } kill(b); return 1; } int main(void) { int T; scanf("%d",&T); while(T--) { scanf("%s%s",str1,str2); if(strlen(str1)!=strlen(str2)) { printf("different\n"); continue; } build(str1,len1,0); build(str2,len2,1); memset(vis,0,sizeof(vis)); if(compare(0,0)) printf("same\n"); else printf("different\n"); } return 0; }
#include <iostream> #include<cstdio> #include <algorithm> #define mod 19997 #define LMT 3002 using namespace std; char str1[LMT],str2[LMT]; int hash[LMT<<2]; char *p; int dfs(int u) { int sum=hash[u+LMT]; while(*p&&*p++=='0') sum=(sum+hash[u]*dfs(u+1))%mod; return (sum*sum)%mod; } void init(void) { for(int i=0;i<LMT<<2;i++) hash[i]=rand()%mod; } int main() { int T,x,y; scanf("%d",&T); init(); while(T--) { scanf("%s%s",str1,str2); p=str1; x=dfs(0); p=str2; y=dfs(0); if(x==y)printf("same\n"); else printf("different\n"); } return 0; }