PAT (Advanced Level) Practice 1067 Sort with Swap (0, i) (25 points) [greedy]

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

Input Specification:

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

The meaning of problems

0 ~ n-1 gives a permutation a, using only swap(a[0], a[x])way to become ordered, the minimum required number of exchanges.

Thinking

Without using only swap(a[0], a[x])limitation: Having identified the need ordered elements is 0 ~ n-1, it is possible to determine the position of each element (i.e. a[i]=i). If a[x]!=x, once swap(a[x], a[a[x]])the elements a[x]will be parked position (position a[x]), but if you a[a[x]]happen to be equal x, then the elements xwill be homing, in this case an exchange allows two elements homing, then the minimum number of exchanges in order to obtain, do you need to perform the exchange in this case it? The only way not needed because all of the elements should sort, without first performing such switching, the total number of such ring structures are sequences not change, such a ring is reduced once said specific exchange . So long as each exchange is meaningful, then the total number of exchanges on specific priorities unrelated to the initial arrangement of only the sole determinant, and exchange.

Now only use swap(a[0], a[x]), can swap(a[0], a[x]), swap(a[0], a[y]), swap(a[0], a[x])be realized swap(a[x], a[y]), can swap(a[0], a[x]), swap(a[0], a[y]), swap(a[0], a[z]), swap(a[0], a[x])be realized swap(a[x], a[y]), swap(a[x], a[z]), it can be seen, the operation requires the original step k, k + 2 steps now required. However, if x = 0, or if k steps. So let x = 0 exchange as many times. That is, be sure to let

while (a[0] != 0) {
    swap(a[0], a[a[0]]);
}

Cycle as many times, so this must be executed first, the other order of exchange do not really matter.

Code

#include <algorithm>
#include <cstdio>

using namespace std;

int a[100005];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        if (a[i] != i) {
            if (i > 0)
                cnt += 2;
            while (a[i] != i) {
                swap(a[i], a[a[i]]);
                ++cnt;
            }
        }
    }

    printf("%d", cnt);
}
Published 184 original articles · won praise 19 · views 20000 +

Guess you like

Origin blog.csdn.net/Exupery_/article/details/104208766