• 1067 Sort with Swap(0, i) (25 分)(贪心)


    Given any permutation of the numbers {0, 1, 2,..., N-1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:

    Swap(0, 1) => {4, 1, 2, 0, 3}
    Swap(0, 3) => {4, 1, 2, 3, 0}
    Swap(0, 4) => {0, 1, 2, 3, 4}

    Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.

    Input Specification:

    Each input file contains one test case, which gives a positive N (<=105) followed by a permutation sequence of {0, 1, ..., N-1}. All the numbers in a line are separated by a space.

    Output Specification:

    For each case, simply print in a line the minimum number of swaps need to sort the given permutation.

    Sample Input:

    10 3 5 7 2 6 4 9 0 8 1

    Sample Output:

    9

    题目大意:

    给出一个n个数的序列,数字为0~n-1的乱序,每次用两两交换的方式而且只能用0和另一个数交换,使序列变成有序的,问最少需要多少步骤。

    分析:

    1.0号为哨兵, 用哨兵与其他数字交换,使其他数字回到有序的位置(最后有序时所处的位置),则排序完成

    2.a[t] = i; 表示t数字当前正在占着哪一个位置。 (如果想实时监测每个数字的位置,可以用 b 数组{b[a[i]] = i } 缓存一下数据,输出查看的)

    3.依次遍历每个位置i,如果当前位置不是与之对应的数字,那么我们让这哨兵来去该数执行操作回到正确位置

    4.数字如何被哨兵执行操作回到序的位置:

    如果哨兵此时不在自己有序的位置上,那就,先让哨兵去让他占的那个位置上的真正应该放的数字回到此位置,即交换哨兵和此数字,我们swap(a[0],a[a0]),直到哨兵在交换的过程中回到了自己的有序位置。字词再次检查该位置是不是应该放的数字(别的数字回到有序位置的时候即哨兵执行操作的过程中,有可能让此位置该有的数字回到位置)。如果此位置不是当前数字,那哨兵和他交换swap(a[0],a[i]),就是让他先去哨兵的有序位置待一会,等下一轮操作,哨兵会把他交换回来的。如果此位置已经是该数字了,那就什么都不做。

    5.当到达最后一个位置时候,两种情况 1)。如果第一个数字和最后一个数字都在自己的有序位置 那ok~ 2).哨兵和最后一个数字互相占着对方的位置,那最后一个数字就是哨兵,交换一次后,哨兵在交换后的位置等待,就是已经回到自己的有序位置,此时排序也是完成的。此过程包括在4里面了,怕你们不理解,单独说一下~

    原文链接:https://blog.csdn.net/liuchuo/article/details/52264805

    柳神代码

    #include <iostream>
    using namespace std;
    int main() {
        int n, t, cnt = 0, a[100010];
        cin >> n;
        for(int i = 0; i < n; i++){
        	cin >> t;
        	a[t] = i;
        }
        for(int i = 1; i < n; i++) {
            if(i != a[i]) {
                while(a[0] != 0) {
                    swap(a[0],a[a[0]]);
                    cnt++;
                }
                if(i != a[i]) {
                    swap(a[0],a[i]);
                    cnt++;
                }
            }
        }
        cout << cnt;
        return 0;
    }
    

    题解

    菜鸡的我并没有看懂柳神的分析,下为算法笔记的解释,比较易懂一些~



    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn=100010;
    int pos[maxn]; //存放各数字当前所处的位置编号
    int main()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("1.txt", "r", stdin);
    #endif
        int n,ans=0; //ans表示总交换次数
        scanf("%d",&n);
        int left=n-1,num; //left存放除0以外不在本位上的数的个数
        for(int i=0;i<n;i++){
            scanf("%d",&num);
            pos[num]=i; //num所处的位置为i
            if(num==i&&num!=0){ //如果除0以外有在本位上的数
                left--; //令left减一
            }
        }
        int k=1; //k存放除0以外当前不在本位上的最小的数
        while(left>0){ //只要还有数不在本位上
            //如果0在本位上,则寻找一个当前不在本位上的数与0交换
            if(pos[0]==0){
                while(k<n){
                    if(pos[k]!=k){ //找到一个当前不在本位上的数k
                        swap(pos[0],pos[k]); //将k与0交换位置
                        ans++;  //交换位置加1
                        break;   //退出循环
                    }
                    k++; //判断k+1是否在本位
                }
            }
            //只要0不在本位,就将0所在位置的数的当前所处位置与0的位置进行交换
            while(pos[0]!=0){
                swap(pos[pos[0]],pos[0]); //将0与pos[0]交换
                ans++;  //交换次数加1
                left--; //不在本位上的数的个数减1
            }
        }
        printf("%d\n",ans);
        return 0;
    }
    

    本文来自博客园,作者:勇往直前的力量,转载请注明原文链接:https://www.cnblogs.com/moonlight1999/p/15613789.html

  • 相关阅读:
    [转]Java中的POJO类
    使用PD进行数据库建模时的问题
    N-Gram模型
    [转] C#开源项目大全
    HTTP Error 503. The service is unavailable.
    abp 取消权限校验
    Oracle expdp/impdp导出导入命令及数据库备份(转)
    Oracle ORA-14102: 只能指定一个 LOGGING 或 NOLOGGING 子句
    Oracle ORA-01940: 无法删除当前连接的用户
    Oracle 把查询的多个字段赋值给多个变量
  • 原文地址:https://www.cnblogs.com/moonlight1999/p/15613789.html
Copyright © 2020-2023  润新知