PTA 7-16 Sort with Swap(0, i) 不用指针数组的简化

Given any permutation of the numbers {0, 1, 2,..., }, 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  nonnegative integers.

Input Specification:

Each input file contains one test case, which gives a positive  () followed by a permutation sequence of {0, 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

 

思路:

就是按照陈越老师讲的思路,但不用另外存一排指针也可以数出来环的个数;

因为我们的目的是数出不同种类的环内包含的元素个数,所以没必要真的每次只交换0,而对于一个环来说,它之所以能形成一个环,就在于:对环内的每个元素,我们只需要移动一次,就可以将其移动到其最终所应该放的位置上。

陈越老师是每遇到一个元素,就按照其索引,找到相应的元素的位置,于是就需要建立一个指针的数组;

但反过来,每次遇到一个元素,就将这个元素移动到它所应在的位置 i ,然后再取 i 处原来存放的元素,进行下一轮的移动,这样也还是形成一个环,只不过移动的方向相反。

 

#include<iostream>
using namespace std;

constexpr int kMaxSize = 100010;

int N;
int origin[kMaxSize];

int loop_swap(int idx){
    int t, cnt = 0, 
        init = origin[idx], //记录当前环的首元素;
        i = origin[idx];  //索引
    bool flag = false; //检查当前环内是否包含0;
    do {
        if (origin[i] == 0)
            flag = true;
        t = origin[i];
        origin[i] = i;
        i = t;
        ++cnt;
    } while (i != init);
    //cnt记录的就是元素的个数;
    if (flag) cnt -= 1;//如果包含0,需要n-1次交换;
    else cnt += 1;
    //首先需要将0转入当前环内,当前环的元素个数增加1;
    //从而需要n+1-1次交换,再加上最初将0转入的那一次交换;
    //总共需要n+1次交换;
    return cnt;
}

int main(){
    ios::sync_with_stdio(false);
    cin >> N;
    int nTime = 0;
    for (int i = 0; i < N; ++i)
        cin >> origin[i];
    for (int i = 0; i < N; ++i){
        if (origin[i] != i){
            nTime += loop_swap(i);
        }
    }
    cout << nTime;
    return 0;
}

 

posted @ 2022-04-21 23:12  HarukiZ  阅读(40)  评论(0编辑  收藏  举报