Codeforces Global Round 23-C

C-Permutation Operations

题目链接:https://codeforces.com/contest/1746/problem/C

此题着实不难,就是看你自己能不能想到那种构造的方法。自己做的时候没有很好的思路,所以参考了官方的解析()。

个人觉得官方解析不错,一步一步来的蛮好。

就着官方题解的思路,说说目前自己的想法。首先我们想要最后得到的排列中逆序数最小,那么可以证明,可以为0,所以肯定要奔着0的目标去,这就意味着对于两两相邻的的元素来说,必定有后一个元素大于前面一个元素,那么当这个条件不满足的时候,我们可以考虑到由于原序列是1到n的一个排列(不重复),这意味着我们可以将第ai次(i<n)操作加到i+1的位置上,这样就保持了ai≤ai+1,那么对a1~an-1都进行这样的操作就可以使得整体保持相邻不递减的状态,又由于不等式是可以传递的,所以说,整体即达到了想要的状态。而最后的an次操作随便加到哪个位置都可以,因为它不会改变最终的状态。

当然可以这样是最简单的思路,但是想到这个思路就是一件难事,所以还是得多练。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x,y,sizeof(x))
//#define int long long

inline ll read()
{
    ll 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*10+ch-48;ch=getchar();}
    return x*f;
}

using namespace std;
const int maxm=1e5+5,inf=0x3f3f3f3f;
int n,a[maxm],b[maxm];

void solve(){
    cin>>n;
    for(int i=1;i<=n;++i) cin>>a[i];
    int p=1;
    for(int i=1;i<=n;++i){
        b[a[i]]=i;
    }
    for(int i=1;i<n;++i){
        if(b[i]!=n)
            cout<<b[i]+1<<' ';
        else cout<<1<<' ';
    }
    if(b[n]!=n) cout<<b[n]+1<<endl;
    else cout<<1<<endl;
    return ;
}

signed main(){
//    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _=1;
    cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

  

posted @ 2022-10-20 17:49  Qiansui  阅读(45)  评论(0)    收藏  举报