Codeforces 1681C

题目描述

给定两个数组 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) (1i,jn;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(1t100) 表示测试数据的组数。

每个测试点的第一行为一个整数 n ( 2 ≤ n ≤ 100 ) n (2 \le n \le 100) n(2n100),表示两个数组中的元素个数。

第二行为 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(1ain)表示第一个数组。

第三行为 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(1bin)表示第二个数组。

输出格式

对每个测试数据,输出答案。如果在 1 0 4 10^4 104步内不可能将两个数组按照非递减排序,输出 − 1 -1 1。否则,输出步数 k ( 0 ≤ k ≤ 1 0 4 ) k (0 \le k \le 10^4) k(0k104)。最后输出每一步的 i i i j ( 1 ≤ i , j ≤ n ; i ≠ j ) j (1 \le i,j \le n; i \neq j) j(1i,jn;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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值