牛客算法入门课练习赛1

E题 交换

题目:

给定一个包含1-n的数列,我们通过交换任意两个元素给数列重新排序

求最少需要多少次交换,能把数组排成按1-n递增的顺序,(数组中的元素互不重复)。

比如 初始状态 5 4 3 2 1 。交换5和1的位置 得到 1 4 3 2 5,再交换4 2的位置得到 1 2 3 4 5.只需要两次即可。

思路:

在原数组中,每个元素添加一个出边指向它最终的位置,这样画完出边后,

最少会成一个环,最多n个环。 然后原理就是, 最少交换次数=结点数n-形成的环数。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
vector<int> v;
bool vis[N];
int main() {
    cin >> n;
    for (int i = 0; i < n; ++i) {
        int x;
        cin >> x;
        v.push_back(x);
    }
    vector<int> sortedv(v);
    sort(sortedv.begin(), sortedv.end());
    map<int, int> mp;
    int len = sortedv.size();
    for (int i = 0; i < len; ++i) mp[sortedv[i]] = i;
    int loop = 0;
    for (int i = 0; i < len; ++i) {
        if (!vis[i]) {
            int t = i;
            while (!vis[t]) {
                vis[t] = true;
                t = mp[v[t]];
            }
            loop++;
    	}
    }
    cout << len - loop;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/all-taker/p/12964707.html