牛客昆明站K.Parallel Sort

题目链接

题意:

给出你长度为 n n n的一个序列(n的全排列),让你通过交换两个数来让他变成下标和数值对应。每一场可以包含多对,但是每个点只能用一次。问你最少需要多少场能使得他变成我们需要的序列(单调递增),并且输出每次操作的两个点。

思路:

我们对样例先进行分析一下来理解题意

4
4 3 2 1

我们可以通过换(4,1),(3,2) {这里指的是数值}
因为没有一个点使用俩遍,所以我们可以通过一次操作来实现。

然后我们进一步分析,每个位置有两个属性分别是:下标

这里是一开始的错误思路:
一开始以为最多是3场:
那么我们可以其实用正常的思路就是确定一个点两两互换
如果我们输入的是这样的
2 3 4 5 6 1 那么我们画出图形就是圆里是值,外面是下标,线是下标应该对应的值
牛客昆明站K.Parallel Sort_第1张图片
那么我们很容易想到把1和2互换(代表里面的值),因为1和2都用过了,所以同一场上不能在换了,我还可以换3和4,5和6换完之后变成,牛客昆明站K.Parallel Sort_第2张图片
整理一下就变成这样的:
牛客昆明站K.Parallel Sort_第3张图片
那么我们在随便换一个假如是2和4,那么就会把2归位 这就是第二场要做的,
第三场要做的就是4和6互换,
但其实这并不是最优的,我们先了解一下这个:

如果牛客昆明站K.Parallel Sort_第4张图片
这样的我们就可以一步互换就可归位,那么我们就可以尽量将原图一场归成这样的,那么再进行一场就可以将所有归位,那么我们怎么实现是个问题

还拿上图来说:
牛客昆明站K.Parallel Sort_第5张图片
我们要凑对的话,我们发现隔一个交换就可以实现,像我们像构造1和2这一对,我们就交换1和3(里面的值);
就变成了这样
牛客昆明站K.Parallel Sort_第6张图片
3这个地方打个星说明他用过这一场我们不能再用,我们看上一步我们并没有用到1,但就把1和2凑出来了,那么我们同理把3放中间,交换3两端的,就可以凑出3和6,剩下4和5自成一对。
这是偶数情况,奇数情况也是这样的,只不过最后一下会让独立出来的一个归位。

int main() {
     
    n=read;
    rep(i,1,n){
     
        a[i]=read;
    }
    for(int i=1;i<=n;i++){
     ///起点
        if(!vis[i]){
     
            int idx=0,tmp=i;
            while(!vis[tmp]){
     
                vis[tmp]=1;
                b[++idx]=tmp;
                tmp=a[tmp];
            }
            if(idx>=2){
     
                int l=2,r=idx;
                while(l<r){
     
                    v[1].push_back({
     b[l],b[r]});
                    swap(b[l],b[r]);
                    l++,r--;
                }
                l=1,r=idx;
                while(l<r){
     
                    v[2].push_back({
     b[l],b[r]});
                    l++,r--;
                }
            }
        }
    }
    int res=0;
    if(v[1].size()) res++;
    if(v[2].size()) res++;
    printf("%d\n",res);
    if(res==0){
     
        return 0;
    }
    for(int i=1;i<=2;i++){
     
        if(!v[i].size()) continue;
        printf("%d ",v[i].size());
        for(int j=0;j<v[i].size();j++)
            printf("%d %d ",v[i][j].first,v[i][j].second);
        puts("");
    }
	return 0;
}

你可能感兴趣的:(构造,思维)