【PAT甲级】1067 Sort with Swap(0,*) (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 (<=10^5^) 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

思路:贪心,  

容易想到的一种情况是:1.如果0不在第一个位置上,就和当前0所在的位置的数交换位置; 这里还有另一种情况

2.当0在第一个位置上,但是还不是有序递增的,所以要选择一个位置上的数交换

注意:交换次数的上限为cnt(cnt表示不在满足题目条件的序列位置上的数的个数),用cnt控制循环次数。 vec[i]=j表示数字i对应的位置j。 上述第二种情形时需要利用贪心思想,具体见代码

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <cmath>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define mem(a,n) memset(a,n,sizeof(a))
typedef long long ll;
typedef unsigned long long ull;
const ll INF=0x3f3f3f3f;
const int N = 1e5+5;

vector<int>vec(N);
int main() {
    int n,x;
    int cnt=0;
    cin>>n;
    rep(i,0,n) {
        cin>>x;
        if(x!=0&&x!=i) cnt++;
        vec[x]=i;
    }
    int id=1,ans=0;
    while(cnt>0) {
        while(vec[0]!=0) {///第一个位置不为0时,就交换
            swap(vec[vec[0]],vec[0]);
            ans++;
            cnt--;
        }
        if(vec[0]==0) {///第一个位置为0时,但序列不符合题目要求即有序递增
            while(id<n) {
                if(vec[id]!=id) {///此时找第一个不在该位置上的数。(贪心) 因为每次从一开始找,所以id以前的位置都是有序递增的。
                    swap(vec[id],vec[0]);
                    ans++;
                    break;
                }
                id++;
            }
//            id=1; ///因此这里不需要重复查找,否则有两个测试点超时
        }
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/feng_zhiyu/article/details/81349208