D. Swap Dilemma
题目大意
给定两个长度为
n
n
n,元素各不相同的数组
a
,
b
a,b
a,b.(没看见元素不同,想了好久没做出来)
可以进行操作 :
a数组选两个坐标
(
l
,
r
)
(l,r)
(l,r),b数组选两个坐标
(
p
,
q
)
(p,q)
(p,q),然后各自交换数组两坐标元素。要求
r
−
l
=
q
−
p
r-l=q-p
r−l=q−p
就是说选等距离元素各自交换
解题思路
看到元素各不相同,就很容易想到用map。
首先,两个数交换两次[a,b]->[b,a]->[a,b]就可以相当于没有操作
距离为3时交换:
可以
1
1
1步直接交换[1x3]->[3x1]
也可以
3
3
3步距离为
2
2
2交换[1x3]->[x13]->[x31]->[3x1]
距离为4时交换:
可以
1
1
1步直接交换[1xx4]->[4xx1]
也可以
5
5
5步距离为
2
2
2交换[1xx4]->[x1x4]->[xx14]->[xx41]->[x4x1]->[4xx1]
发现一步距离无论是多少的交换,都等同于奇数次距离为2交换。所以可以直接找把b数组交换为a数组时,一共需要多少步,不管这一步的距离是多少都是奇数次距离为2的交换,如果是偶数,则可以实现
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+6;
int a[N], b[N];
map<int, int> mp;
void solve()
{
int n;
cin >> n;
for(int i=1;i<=n;i++)
cin >> a[i];
for(int i=1;i<=n;i++){
cin>>b[i];
mp[b[i]]=i;
}
int ans=0;
for(int i=1;i<=n;i++){
if (b[i] == a[i])
continue;
//两个数组有元素冲突
if (!mp[a[i]]){
cout << "NO\n";
return;
}
//交换
int x=mp[a[i]];
swap(b[i],b[x]);
mp[b[i]]=i;
mp[b[x]]=x;
ans+=1;
}
if (ans%2 == 0){
cout<<"YES\n";
}else cout<<"NO\n";
mp.clear();
}
signed main()
{
int T;
cin>>T;
while(T--)
solve();
return 0;
}