教育场129 c题
c.双倍排序
题意
给定两个数组 a 和 b,均由 n 个整数组成。
在一个步骤中,您可以选择两个索引 i 和 j (1≤i,j≤n; i≠j) 并将 ai 与 aj 和 bi 与 bj 交换。 您必须在两个阵列中执行交换。
您最多可以执行 10^4 次移动(可能为零)。 你可以让两个数组最后都按非递减顺序排序吗? 如果可以,请打印任何使两个数组都排序的移动序列。
输入
第一行为测试数量t (1≤t≤100) 。
第二行为长度n (2≤n≤100) ,然后是 a1,a2,…,an (1≤ai≤n) ,b1,b2,…,bn(1≤bi≤n)
输出
对于每个测试用例,打印答案。 如果不可能在最多 104 次移动中使两个数组按非递减顺序排序,则打印 -1。 否则,首先打印移动次数 k (0≤k≤10^4)。 然后为每一步打印 i 和 j (1≤i,j≤n; i≠j)。
如果有多个答案,则打印其中任何一个。 您不必尽量减少移动次数。
题目分析
重写cmp的排序,然后一一比较是否无解,最后根据排序后的结果寻找输出位置(注意:cmp不能加等于号!!)
#include<bits/stdc++.h>
using namespace std;
struct Node {
int a,b;
};
bool cmp(Node x,Node y) {
if(x.a!=y.a) {
return x.a <= y.a;
}
return x.b <= y.b;
}
Node no[1007],pre[1007];
pair<int,int>ans[30000];
int main() {
int tc;
cin >> tc;
while(tc--) {
int n;
cin >> n;
for(int i = 1 ; i <= n ; i++)
cin >> no[i].a;
for(int i = 1 ; i <= n ; i++)
cin >> no[i].b;
for(int i = 1 ; i <= n ; i++)
pre[i] = no[i];
sort(no+1,no+n+1,cmp);
bool flag = 1;
for(int i = 2 ; flag && i <= n ; i++) {
if(no[i].a < no[i-1].a || no[i].b < no[i-1].b ) {
flag = 0;
}
}
if(!flag) {
cout << -1 << endl;
continue;
}
int cnt = 0;
for(int i = 1 ; i <= n ; i++) {
if(no[i].a != pre[i].a || no[i].b != pre[i].b) {
for(int j = i+1 ; j <= n ; j++) {
if(pre[j].a == no[i].a && pre[j].b == no[i].b) {
Node t = pre[j];
pre[j] = pre[i];
pre[i] = t;
ans[++cnt] = {i,j};
}
}
}
}
cout << cnt << endl;
for(int i = 1 ; i <= cnt ; i++) {
cout << ans[i].first << " " << ans[i].second << endl;
}
}
}

浙公网安备 33010602011771号