题目描述
给定两个数组 a a a和 b b b,都含有 n n n个整数。
每一步你可以选择两个索引 i i i和 j j j ( 1 ≤ i , j ≤ n ; i ≠ j ) ( 1\le i,j \le n; i \neq j) (1≤i,j≤n;i=j)且同时交换 a i a_i ai和 a j a_j aj、 b i b_i bi和 b j b_j bj。每个交换必须在两个数组内同时进行。
你被允许执行至多 1 0 4 10^4 104步。你能将两个数组变成非递减吗?如果能,请输出你的操作过程。
输入格式
第一行为一个整数 t ( 1 ≤ t ≤ 100 ) t (1 \le t \le 100) t(1≤t≤100) 表示测试数据的组数。
每个测试点的第一行为一个整数 n ( 2 ≤ n ≤ 100 ) n (2 \le n \le 100) n(2≤n≤100),表示两个数组中的元素个数。
第二行为 n n n个整数 a 1 , a 2 , . . . , a n ( 1 ≤ a i ≤ n ) a_1,a_2,...,a_n (1 \le a_i \le n) a1,a2,...,an(1≤ai≤n)表示第一个数组。
第三行为 n n n个整数 b 1 , b 2 , . . . , b n ( 1 ≤ b i ≤ n ) b_1,b_2,...,b_n (1 \le b_i \le n) b1,b2,...,bn(1≤bi≤n)表示第二个数组。
输出格式
对每个测试数据,输出答案。如果在 1 0 4 10^4 104步内不可能将两个数组按照非递减排序,输出 − 1 -1 −1。否则,输出步数 k ( 0 ≤ k ≤ 1 0 4 ) k (0 \le k \le 10^4) k(0≤k≤104)。最后输出每一步的 i i i和 j ( 1 ≤ i , j ≤ n ; i ≠ j ) j (1 \le i,j \le n; i \neq j) j(1≤i,j≤n;i=j)。
如果有多种答案,输出其中之一。不需要最小化步数。
输入输出样例
输入 | 输出 |
---|---|
3 2 1 2 1 2 2 2 1 1 2 4 2 3 1 2 2 3 2 3 | 0 -1 3 3 1 3 2 4 3 |
题解
按照 a a a排序后,再按照相同的 a a a将 b b b从小到大排序。
然后存结果。
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int a,b,index;
}a[105];
int t;
int n;
int cnt;
int ans[100005][2];
bool cmp(Node a,Node b)
{
if(a.a==b.a)
{
if(a.b==b.b) return a.index<b.index;
return a.b<b.b;
}
return a.a<b.a;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i].a);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].b);
a[i].index=i;
}
sort(a+1,a+n+1,cmp);
bool flag=true;
for(int i=1;i<n;i++)
{
if(a[i].a>a[i+1].a||a[i].b>a[i+1].b)
{
flag=false;
break;
}
}
if(!flag)
{
printf("-1\n");
continue;
}
cnt=0;
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(a[i].index>a[j].index)
{
Node c=a[i];
a[i]=a[j];
a[j]=c;
ans[++cnt][0]=i;
ans[cnt][1]=j;
}
}
}
printf("%d\n",cnt);
for(int i=cnt;i>=1;i--)
{
printf("%d %d\n",ans[i][0],ans[i][1]);
}
}
return 0;
}