思路
- 首先,如果a中有一个字符出现两次以上,就可以把这两个字符先放在一起,这样在b中做反转时候,就可以两两做反转,这样类似与冒泡排序一样,在a中就只要交换着两个相同的字符就可以了,所以这样如果两个字符串各个字符数相同情况下,出现一个字符两次及以上就一定可以变为相同
- 如果不符合以上情况,那么只要从前往后遍历,如果a[i]!=b[i],那么就去后面找一个b[j]==a[i],用冒泡排序的方式排上来,这样如果排了奇数次,就把a[i+1]和a[i+2]反一下,这样就符合题目要求了,最后判断一下最后两个字符是否和a中的相同即可
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
const int N=2e5+5;
char a[N];
char b[N];
int num1[30];int num2[30];
void solve(int pos){
int res=0;
int idx=pos;
while(a[pos]!=b[idx])idx++;
for(int i=idx;i!=pos;i--){
b[i]=b[i-1];
}
b[pos]=a[pos];
if((idx-pos)%2)swap(a[pos+1],a[pos+2]);
}
int main(){
int T;
cin >> T;
while(T--){
int n;
memset(num1,0,sizeof num1);
memset(num2,0,sizeof num2);
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
num1[a[i]-'a'+1]++;
}
for(int i=1;i<=n;i++){
cin >> b[i];
num2[b[i]-'a'+1]++;
}
bool flag=true;
for(int i=1;i<=26;i++){
if(num1[i]!=num2[i]){
flag=false;break;
}
}
if(!flag){
cout << "NO\n";
continue;
}
flag=false;
for(int i=1;i<=26;i++){
if(num1[i]>1){
flag=true;
break;
}
}
if(flag){
cout << "YES\n";
continue;
}
for(int i=1;i<=n-2;i++){
if(a[i]!=b[i])solve(i);
}
if(a[n-1]!=b[n-1])cout << "NO\n";
else cout << "YES\n";
}
}