Assumption is All You Need
https://codeforces.com/gym/103409/problem/D
①从左往右按下标遍历,若 a [ i ] = b [ i ] a[i]=b[i] a[i]=b[i] 则无需再调整,写几个样例会发现调整会不断破坏更前面已经匹配好的位置,所以已经匹配好的就不考虑再做操作了。
②若当前 a [ i ] < b [ i ] a[i]<b[i] a[i]<b[i] ,则直接没有答案,因为是操作逆序对,向后考虑操作只能换来更小值,不可能匹配上。
③若 a [ i ] > b [ i ] a[i]>b[i] a[i]>b[i] ,我们不能直接交换在 a a a 中等于 b [ i ] b[i] b[i] 的位置,因为我们在途中可以进行一些使得后续操作更优的交换。我们此时可以不断操作的也就是,某个 j j j 满足 a [ j ] < a [ i ] a[j]<a[i] a[j]<a[i] (因必须逆序)且 a [ j ] ≥ b [ i ] a[j]\geq b[i] a[j]≥b[i] (换了小于的就变回②了),那么我们只要遇到这样的位置就发生交换,因为这样可以尽可能使得比较大的元素在前面,尽可能拓展后续操作的可能性,直至交换完出现 a [ i ] = b [ i ] a[i]=b[i] a[i]=b[i] 的情况停止。
#include <bits/stdc++.h>
using namespace std;
const int N = 3000;
int n;
int a[N], b[N];
vector< pair<int, int> > ans;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int T; scanf("%d", &T);
while(T--) {
ans.clear();
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &b[i]);
}
bool ok = true;
for (int i = 1; i <= n; ++i) {
if (a[i] == b[i]) continue;
if (a[i] < b[i]) {
ok = false;
break;
}
int j = i + 1;
while(j <= n && a[i] != b[i]) {
if (a[j] < a[i] && a[j] >= b[i]) {
swap(a[i], a[j]);
ans.push_back({i, j});
}
j++;
}
if (a[i] != b[i]) {
ok = false;
break;
}
}
if (ok) {
printf("%d\n", (int)ans.size());
for (auto v : ans) {
printf("%d %d\n", v.first, v.second);
}
}
else {
puts("-1");
}
}
}