欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

牛客网 NC207078 交换 贪心算法

程序员文章站 2024-02-12 22:41:52
...

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;
}


联系邮箱:aaa@qq.com

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

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

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

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

牛客网 NC207078 交换 贪心算法