CodeForces - 559B Equivalent Strings

Today on a lecture about strings Gerald learned a new definition of string equivalency. Two strings a and b of equal length are called equivalent in one of the two cases:

  1. They are equal.
  2. If we split string a into two halves of the same size a1 and a2, and string binto two halves of the same size b1 and b2, then one of the following is correct:
    1. a1 is equivalent to b1, and a2 is equivalent to b2
    2. a1 is equivalent to b2, and a2 is equivalent to b1

As a home task, the teacher gave two strings to his students and asked to determine if they are equivalent.

Gerald has already completed this home task. Now it's your turn!

Input

The first two lines of the input contain two strings given by the teacher. Each of them has the length from 1 to 200 000 and consists of lowercase English letters. The strings have the same length.

Output

Print "YES" (without the quotes), if these two strings are equivalent, and "NO" (without the quotes) otherwise.

Examples

扫描二维码关注公众号,回复: 4769390 查看本文章

Input

aaba
abaa

Output

YES

Input

aabb
abab

Output

NO

Note

In the first sample you should split the first string into strings "aa" and "ba", the second one — into strings "ab" and "aa". "aa" is equivalent to "aa"; "ab" is equivalent to "ba" as "ab" = "a" + "b", "ba" = "b" + "a".

In the second sample the first string can be splitted into strings "aa" and "bb", that are equivalent only to themselves. That's why string "aabb" is equivalent only to itself and to string "bbaa".

题目大意:给定两个等长的字符串a,b,问两个字符串是否是等价的,

等价的定义:1 如果两个字符串相等则是等价的,

                         2 如果字符串长度为偶数,则将a分成两个等长的字串a1,a2,将b分成两个等长的字串b1,b2,如果满足a1==b1&&a2==b2或者a1==b2&&a2==b1,则认为a,b等价

解题思路:可以用分治思想来做,如果当前两个串相等,返回true,否则判断当前串长度是否为偶数,是的话,将两个串分成四个字串a1,a2,b1,b2,依次判断是否符合定义,符合返回true,否则继续进行上述操作,刚开始使用strncpy函数来将两个串分成四个串,然后用strcmp函数进行判断是否相等,不幸的是在第91组测试时TLE了,想了一想每一次递归是都要进行串的赋值,会花费很多的时间,所以我简化了一下,每一次不用strncpy函数来分字串,用两个变量来标记每一个串的起始位置和终止位置,然后在进行判断,这样就会省很多时间,题目时间限制是2000ms,简化后用了1482ms过了,开心

简化之前TLE的代码:

#include<iostream>
#include<cstring>
using namespace std;
const int maxn=2e5+100;
char a[maxn],b[maxn];
int judge(char a1[],char a2[],char b1[],char b2[])
{
	if((!strcmp(a1,b1)&&!strcmp(a2,b2))||(!strcmp(a1,b2)&&!strcmp(a2,b1)))
		return 1;
	if(!strcmp(a1,b1))//a1==b1,但a2!=b2 
		return 2;
	if(!strcmp(a2,b2))//a2==b2,但a1!=b1;
		return 3;
	if(!strcmp(a1,b2))//a1==b2,但a2!=b1; 
		return 4;
	if(!strcmp(a2,b1))//a2==b1,但a1!=b2
		return 5;
	return 6; 
} 
bool solve(char a[],char b[],int n)
{
	if(!strcmp(a,b))
		return true;
	if(n%2!=0)//奇数不等价 
		return false; 
	int mid=n/2;
	if(mid)
	{
		char a1[mid+1],a2[mid+1],b1[mid+1],b2[mid+1];//四个子串 
		strncpy(a1,a,mid);
		a1[mid]='\0';
		strncpy(a2,a+mid,mid);
		a2[mid]='\0';
		strncpy(b1,b,mid);
		b1[mid]='\0';
		strncpy(b2,b+mid,mid);
		b2[mid]='\0';
		int term=judge(a1,a2,b1,b2);
		switch(term)
		{
			case 1://相等 
				{
					return true;
					break;
				}
			case 2://a1==b1,但a2!=b2 这时只需判断字a2和b2即可,下面情况相同 
				{
					bool flag=solve(a2,b2,mid);
					if(flag)
						return true;
					break;
				}
			case 3:
				{
					bool flag=solve(a1,b1,mid);
					if(flag)
						return true;
					break;
				}
			case 4:
				{
					bool flag=solve(a2,b1,mid);
					if(flag)
						return true;
					break;
				}
			case 5:
				{
					bool flag=solve(a1,b2,mid);
					if(flag)
						return true;
					break;
				}
			case 6://分成的四个字串没有相同的,就有四种情况,分别判断 
				{
					bool flag=solve(a1,b1,mid)&&solve(a2,b2,mid)||solve(a1,b2,mid)&&solve(a2,b1,mid);
					if(flag)
						return true;
					break;
				}
		}
	}
	return false;
}

int main()
{
	scanf("%s%s",a,b);
	int n;
	n=strlen(a);
	if(!strcmp(a,b))
		printf("YES\n");
	else if(n%2!=0)
		printf("NO\n");
	else
	{
		bool flag=solve(a,b,n);
		if(flag)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
} 

 简化之后AC代码:

#include<iostream>
#include<cstring>
using namespace std;
const int maxn=2e5+100;
char a[maxn],b[maxn];
bool cmp(char a[],char b[],int f1,int L1,int f2,int L2)//判断字串是否相同 
{
	bool flag=false;
	int i=f1,j=f2;
	while(i<L1&&j<L2)
	{
		if(a[i++]!=b[j++])
		{
			flag=true;
			break;
		}
	}
	return flag;
}
int judge(char a[],char b[],int f1,int L1,int f2,int L2,int f3,int L3,int f4,int L4)
{
	if((!cmp(a,b,f1,L1,f3,L3)&&!cmp(a,b,f2,L2,f4,L4))||(!cmp(a,b,f1,L1,f4,L4)&&!cmp(a,b,f2,L2,f3,L3)))
		return 1;
	if(!cmp(a,b,f1,L1,f3,L3))//a1==b1,但a2!=b2 
		return 2;
	if(!cmp(a,b,f2,L2,f4,L4))//a2==b2,但a1!=b1;
		return 3;
	if(!cmp(a,b,f1,L1,f4,L4))//a1==b2,但a2!=b1; 
		return 4;
	if(!cmp(a,b,f2,L2,f3,L3))//a2==b1,但a1!=b2
		return 5;
	return 6; 
} 
bool solve(char a[],char b[],int n,int f1,int L1,int f2,int L2)
{
	if(!cmp(a,b,f1,L1,f2,L2))
		return true;
	if(n%2!=0)//奇数不等价
		return false; 
	int mid=n/2;
	if(mid)
	{
		int term=judge(a,b,f1,f1+mid,f1+mid,L1,f2,f2+mid,f2+mid,L2);
		switch(term)//     | 子串a1 |   a2    |   b1    |   b2    /
		{
			case 1:
				{
					return true;
					break;
				}
			case 2://a1==b1,但a2!=b2 这时只需判断字a2和b2即可,下面情况相同 
				{
					bool flag=solve(a,b,mid,f1+mid,L1,f2+mid,L2);
					if(flag)
						return true;
					break;
				}
			case 3:
				{
					bool flag=solve(a,b,mid,f1,f1+mid,f2,f2+mid);
					if(flag)
						return true;
					break;
				}
			case 4:
				{
					bool flag=solve(a,b,mid,f1+mid,L1,f2,f2+mid);
					if(flag)
						return true;
					break;
				}
			case 5:
				{
					bool flag=solve(a,b,mid,f1,f1+mid,f2+mid,L2);
					if(flag)
						return true;
					break;
				}
			case 6:
				{
					bool flag=solve(a,b,mid,f1,f1+mid,f2,f2+mid)&&solve(a,b,mid,f1+mid,L1,f2+mid,L2)||solve(a,b,mid,f1,f1+mid,f2+mid,L2)&&solve(a,b,mid,f1+mid,L1,f2,f2+mid);
					if(flag)
						return true;
					break;
				}
		}
	}
	return false;
}

int main()
{
	scanf("%s%s",a,b);
	int n;
	n=strlen(a);
	if(!cmp(a,b,0,n,0,n))
		printf("YES\n");
	else if(n%2!=0)
		printf("NO\n");
	else
	{
		bool flag=solve(a,b,n,0,n,0,n);
		if(flag)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_40707370/article/details/85233761