直接暴搜,,,,,
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
char s1[210000] , s2[210000] ;
int solve(int l1,int r1,int l2,int r2) {
int i , mid1 , mid2 ;
for(i = 0 ; i <= (r1-l1) ; i++)
if( s1[l1+i] != s2[l2+i] ) break ;
if( i > (r1-l1) ) return 1 ;
if( (r1-l1+1)%2 ) return 0 ;
mid1 = (l1+r1)/2 ;
mid2 = (r2+l2)/2 ;
if( solve(l1,mid1,l2,mid2) && solve(mid1+1,r1,mid2+1,r2) ) return 1 ;
if( solve(l1,mid1,mid2+1,r2) && solve(mid1+1,r1,l2,mid2) ) return 1 ;
return 0 ;
}
int main() {
int l1 , l2 ;
while( scanf("%s %s", s1, s2) != EOF ) {
l1 = strlen(s1) ;
l2 = strlen(s2) ;
if( l1 != l2 || !solve(0,l1-1,0,l2-1) )
printf("NO\n") ;
else
printf("YES\n") ;
}
return 0 ;
}
最小表示法,将s1折半深搜,然后判断左侧子串和右侧字串的关系,如果左侧子串大,交换左右字串,使得最后s1是按照规则可以得到最小的串。s2按照同样的方式转换,然后比较两个串
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
char s1[210000] , s2[210000] ;
char c ;
void solve(int l,int r,char *s) {
if( (r-l+1)%2 ) return ;
int i , mid = (l+r)/2 ;
solve(l,mid,s) ;
solve(mid+1,r,s) ;
for(i = 0 ; i < (r-l+1)/2 ; i++) {
if( s[l+i] > s[mid+1+i] ) break ;
if( s[l+i] < s[mid+1+i] ) return ;
}
if( i == (r-l+1)/2 ) return ;
for(i = 0 ; i < (r-l+1)/2 ; i++) {
c = s[l+i] ; s[l+i] = s[mid+1+i] ; s[mid+1+i] = c ;
}
}
int main() {
int l1 , l2 ;
while( scanf("%s %s", s1, s2) != EOF ) {
l1 = strlen(s1) ;
l2 = strlen(s2) ;
solve(0,l1-1,s1) ;
solve(0,l2-1,s2) ;
if( l1 != l2 || strcmp(s1,s2) )
printf("NO\n") ;
else
printf("YES\n") ;
}
return 0 ;
}