hh的蓝桥杯每日一题(交换瓶子)

15.交换瓶子 - 蓝桥云课

方法一:贪心做法

  • 对于位置 i,如果 a[i] ≠ i

  • 就把 a[i] 和 a[a[i]] 交换(把当前数字放到它应该去的位置)

  • 这样每次交换都能让至少一个数字归位

  • 重复直到 a[i] = i

cpp 复制代码
#include<iostream>
using namespace std;

const int N = 10010;
int n;
int a[N];

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    
    int ans = 0;
    
    // 贪心:直接把每个数放到正确位置
    for(int i = 1; i <= n; i++) {
        while(a[i] != i) {  // 如果当前位置的数不对
            swap(a[i], a[a[i]]);  // 把它和它应该在的位置交换
            ans++;
        }
    }
    
    cout << ans << endl;
    return 0;
}

方法二:利用环的性质(交换排序最小交换问题)

这个问题实际上可以转化为图论中的环分解问题

  • 把排列看作一个置换(permutation)

  • 每个元素应该回到它的正确位置(值 i 应该在位置 i)

  • 通过交换操作,我们可以将排列分解为若干个环

  • 最小交换次数 = 所有环的大小之和 - 环的个数

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N = 10010;  // 题目说 N<10000,所以开大一点
int n;
int a[N];
bool st[N];  // 标记数组,记录位置是否访问过

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)  // 注意:题目瓶子编号从1开始
    {
        cin >> a[i];
    }
    
    int ans = 0;
    
    // 遍历所有位置
    for(int i = 1; i <= n; i++)
    {
        // 如果当前位置的值不是 i,且没有被访问过
        if(a[i] != i && !st[i])
        {
            // 找到当前元素所在的环
            int j = i;
            int cnt = 0;  // 环的大小
            
            while(!st[j])
            {
                st[j] = true;  // 标记已访问
                j = a[j];      // 跳到这个位置应该放的元素的位置
                cnt++;
            }
            
            // 环的大小为 cnt,需要 cnt-1 次交换
            ans += (cnt - 1);
        }
    }
    
    cout << ans << endl;
    return 0;
}
相关推荐
努力学算法的蒟蒻5 小时前
day75(2.3)——leetcode面试经典150
面试·职场和发展
觉醒大王5 小时前
硕士/博士研究生避坑指南
笔记·深度学习·学习·自然语言处理·职场和发展·学习方法
华清远见成都中心5 小时前
GPIO(通用输入输出)面试中高频问题
单片机·面试·职场和发展
仰泳的熊猫7 小时前
题目1434:蓝桥杯历届试题-回文数字
数据结构·c++·算法·蓝桥杯
沧澜sincerely10 小时前
蓝桥杯算法练习
算法·职场和发展·蓝桥杯
YuTaoShao11 小时前
【LeetCode 每日一题】3013. 将数组分成最小总代价的子数组 II
算法·leetcode·职场和发展
爱尔兰极光11 小时前
LeetCode 热题 100--字母异位词分组
算法·leetcode·职场和发展
_OP_CHEN11 小时前
【算法基础篇】(五十三)隔板法指南:从 “分球入盒” 到不定方程,组合计数的万能解题模板
算法·蓝桥杯·c/c++·组合数学·隔板法·acm/icpc
XH华1 天前
备战蓝桥杯,第七章:函数与递归
职场和发展·蓝桥杯
七禾页丫1 天前
面试记录14 上位机软件工程师
面试·职场和发展