牛客网 NC207078 交换 贪心算法

1. 题目描述

1.1. Limit

Time Limit: C/C++ 1秒,其他语言2秒

Memory Limit: C/C++ 262144K,其他语言524288K

1.2. Problem Description

牛客幼儿园的小朋友课间操时间需要按照学号从小到大排队,但是他们太小了只能站成一列顺序却不对,现在幼儿园的阿姨需要帮忙交换小朋友的位置让他们最终有序,阿姨希望能尽快完成交换操作,问最少需要交换多少次,才能使得小朋友们从小到大排好。注意:每个小朋友的学号不同,但是未必连续,因为可能有小朋友请假了没有来。

1.3. Input

第一行一个整数 NN

接下来 NN 行每行一个整数,为小朋友们的队列。

1.4. Output

一个整数表示小朋友们的最小交换次数。

1.5. Sample Input

3
2
1
3

1.6. Sample Output

1

1.7. Note

N100000N\leq100000,其他整数均 109\leq 10^9

1.8. Source

牛客网 NC207078 交换

2. 解读

先将数组排序,我们就得到每个数排序后的位置。

然后对原始的数组进行遍历,如果它的位置和排序后的位置不一致,则将其交换到排序后的位置。每次交换至少将一个数交换到其应该所属的位置,有时能够同时将两个数都交换到其应该所属的位置。

记录交换次数,遍历完以后就得到了最小交换次数。

3. 代码

#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
const int N = 2e6 + 5;
int a[N];
int b[N];
map<int, int> mp;
int main()
{
    int n;
    // 输入
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        b[i] = a[i];
        mp[a[i]] = i;
    }
    // 排序
    sort(b, b + n);
    int sum = 0;
    // 计算
    for (int i = 0; i < n; i++) {
        if (a[i] != b[i]) {
            int x = mp[a[i]], y = mp[b[i]];
            // 交换
            swap(a[x], a[y]);
            mp[a[x]] = x;
            mp[a[y]] = y;
            // 累加
            sum++;
        }
    }
    cout << sum;
}


联系邮箱:[email protected]

CSDN:https://me.csdn.net/qq_41729780

知乎:https://zhuanlan.zhihu.com/c_1225417532351741952

公众号:复杂网络与机器学习

欢迎关注/转载,有问题欢迎通过邮箱交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章