题目思路

从交换相邻这里,我们可以明显看出来,这有些类似冒泡排序。

但是,我们要来思考一下怎样情况输出 NO

我们就用冒泡排序的代码来分析一下。为了方便分析,就用 for 循环版的。

for(int i=1;i<=n-1;i++)
{
    for(int j=1;j<=n-i;j++)
    {
        if(a[j]<a[j+1])
        {
            swap(a[j],a[j+1]);
        }
    }
}

我们能很快的反应出来,$(n-1)\times (n-i)$ 肯定是比 $n^2$ 要小的。

所以,$n^2$ 的操作绰绰有余。

因此,我们只要判断数组元素是否相同就可以了,不用考虑能否在 $n^2$ 次操作内完成。

我们先写出判断一样的代码。

int n=read();
int a[n+1],b[n+1],c[n+1],d[n+1];
for(int i=1;i<=n;i++)
{
    cin>>a[i];
    c[i]=a[i];
}
for(int i=1;i<=n;i++)
{
    cin>>b[i];
    d[i]=b[i];
}
sort(c+1,c+n+1);
sort(d+1,d+n+1);
//因为不能打乱ab数组,就用别的数组代替。如果排序后一模一样,里面元素也一样。
for(int i=1;i<=n;i++)
{
    if(c[i]!=d[i]){puts("NO");return;}//判断ab数组元素是否相同
}

接着,如果可以构造出来,我们就可以每次确定一个数的位置,最后就能创造出来。

puts("YES");
for(int i=1;i<=n;i++)//循环b的元素
{
    int x;
    for(int j=i;j<=n;j++)
    {
        if(a[j]==b[i])
        {
            x=j;//找位置
            break;
        }
    }
    for(int j=x;j>i;j--)//交换
    {
        swap(a[j],a[j-1]);
        cout<<j<<" "<<j-1<<'\n';
    }
}
cout<<0<<" "<<0<<'\n';

完整代码

完整代码戳这

#include<bits/stdc++.h>
using namespace std;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
void solve()
{
    int n=read();
    int a[n+1],b[n+1],c[n+1],d[n+1];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        c[i]=a[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
        d[i]=b[i];
    }
    sort(c+1,c+n+1);
    sort(d+1,d+n+1);
    for(int i=1;i<=n;i++)
    {
        if(c[i]!=d[i]){puts("NO");return;}
    }
    puts("YES");
    for(int i=1;i<=n;i++)
    {
        int x;
        for(int j=i;j<=n;j++)//这里赛时写错过了,事后被同学 hack 了 QwQ
        {
            if(a[j]==b[i])
            {
                x=j;
                break;
            }
        }
        for(int j=x;j>i;j--)
        {
            swap(a[j],a[j-1]);
            cout<<j<<" "<<j-1<<'\n';
        }
    }
    cout<<0<<" "<<0<<'\n';
}
int main()
{
    int t=read();
    while(t--)
    {
        solve();
    }
    return 0;
}

最后修改:2023 年 04 月 23 日
v我50吃疯狂星期四