Codeforces-1681 C: Double Sort
题目传送门:Codeforces-1681 C
题目
题目截图
样例描述
题目大意
给定两个长度为 n n n 的数组 a 、 b a、b a、b。可以执行的操作为选择两个下标 i , j i,j i,j,同时交换 a i 、 a j a_i、a_j ai、aj 和 b i 、 b j b_i、b_j bi、bj,问能否将两个数组都排成不降序列。
题目解析
首先题目给的范围是
1
0
4
10^4
104 次交换,然而,我们的数组长度最多也就
100
100
100,这意味着我们可以把两两都交换一遍,因此这个交换范围我们可以忽略,最后直接找出排序顺序即可。
之后的问题是如何排序,首先,如果我们知道偏序的概念,我们可以直接定义一个偏序关系为
a
i
≤
a
j
a_i \le a_j
ai≤aj 且
b
i
≤
b
j
b_i \le b_j
bi≤bj,如果能够排序成功,那么就说明我们可以用题目所说的交换排序。然而,用这种偏序有时候是不可比的,因为没有完全性。但我们可以用另一种方法去代替它,使得它变成全序关系,即先以
a
i
≤
a
j
a_i \le a_j
ai≤aj 排序,再以
b
i
≤
b
j
b_i \le b_j
bi≤bj 排序,加入先后顺序之后,我们可以直接对两个数组进行排序。显然,如果能够排序后两个数组都有序,那么我们就得到了最终的数组。
之后我们用排序算法,将排好序的数组与原数组进行比较,从小到大,我们逐个交换元素,让原数组变成排好序的数组,就可以得到交换序列了。
Code
#include <bits/stdc++.h>
using namespace std;
int main() {
int t, n;
cin >> t;
while(t--) {
cin >> n;
vector<pair<int, int>> vec(n, make_pair(0, 0));
for(int i=0; i<n; ++i)
cin >> vec[i].first;
for(int i=0; i<n; ++i)
cin >> vec[i].second;
vector<pair<int, int>> p(vec);
sort(vec.begin(), vec.end());
bool fl = false;
for(int i=1; i<n; ++i) {
if(vec[i].second < vec[i-1].second) {
cout << -1 << endl;
fl = true;
break;
}
}
if(!fl) {
vector<pair<int, int>> ans;
for(int i=0; i<n; ++i) {
if(vec[i].first != p[i].first || vec[i].second != p[i].second) {
for(int j=i+1; j<n; ++j) {
if(vec[i].first == p[j].first && vec[i].second == p[j].second) {
ans.push_back(make_pair(i+1, j+1));
swap(p[i], p[j]);
break;
}
}
}
}
cout << ans.size() << endl;
for(int i=0; i<ans.size(); ++i)
cout << ans[i].first << " " << ans[i].second << endl;
}
}
return 0;
}