交换瓶子问题(暴力求解 + 图论解法)

交换瓶子问题

文章目录

前言

知道题目用暴力算法是可以过的,注意数据范围是1~10000,卡在一个微妙的地方,不免让人想用暴力算法,但是我们现在又不在赛场上,自然是多多益善,在这里还会介绍图论的解法,喜欢的小伙伴可以点个赞啦。

题目描述

有 N 个瓶子,编号 1∼N,放在架子上。

比如有 5 个瓶子:

2 1 3 5 4

要求每次拿起 2个瓶子,交换它们的位置。

经过若干次后,使得瓶子的序号为:

1 2 3 4 5

对于这么简单的情况,显然,至少需要交换 2 次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式

第一行包含一个整数 N,表示瓶子数量。

第二行包含 N 个整数,表示瓶子目前的排列状况。

输出格式

输出一个正整数,表示至少交换多少次,才能完成排序。

数据范围
1≤N≤10000,

输入样例1:

5

3 1 2 5 4

输出样例1:

3

输入样例2:

5

5 4 3 2 1

输出样例2:

2

暴力解法【能过】

类似于选择排序这样的,与当前位置不同的数直接在后面的数组当中找到符合的数与之交换,前面的数已经排好序了,不需要考虑

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N =1e4+7;
int a[N];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(a[i]!=i){
            for(int j=i+1;j<=n;j++){
                if(a[j]==i) swap(a[j],a[i]),cnt++;
            }        
        }
    }
    cout<<cnt;
}

图论解法

知识预备【交换环】

我们先举例分析:看下图

我们可以得到 3 个环

每个环是闭环,入度为 1 ,出度为 1。构建方式如上图所示

下面我们对环进行操作:

假设有个大环:

每次分解只能产生一个环
而我们最终的目的是将所有大环分解成一个一个小环,每个瓶子回到了本该属于自己3的位置,每次的分解操作只是一次交换

swap(a[ i ] , a [ j ])

现在我们有 n 个数, 假设产生 k 个环 ,那么我们至少需要 n - k 步操作才能使得大环变成一个一个最小环。而只要有环的长度>=2,那么我们就可以将其分解开来,使得可以在 n - k 步操作完成全部分解

现在我们只要求环的数量就行【类似于链表】 ,那么直接上代码

代码

解析都在代码注释当中呦

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N =1e4 + 7;
bool st[N];//判断一个数是否有被纳入环内
int a[N];//存储原数组

int main(){
    int n;cin>>n;
    int ans=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++){
        if(!st[i]){//从 1 号位开始枚举
            ans++;
            for(int j=i;!st[j];j=a[j]){
                //这里j=a[j]是本来的数--》本来数的位置上 的 现在的数
                st[j]=true;
            }
        }
    }
    cout<<n-ans<<endl;
}

暴力做法和图论做法的对比

上面的是图论,下面的是暴力。

总结

这边博客介绍了 2 种思路,图论的做法比较新奇,上述的结论也适合在其他类型的题目当中求解,后续还会更新图论相关的内容,喜欢的小伙伴可以点个关注啦

相关推荐
武昌库里写JAVA15 分钟前
人工智能不是人工“制”能
c语言·开发语言·数据结构·算法·二维数组
buaichifanqie1 小时前
离散化算法
c++·算法·离散化
ganjiee00072 小时前
力扣(leetcode)每日一题 2374 边积分最高的节点
算法·leetcode
凌肖战2 小时前
力扣上刷题之C语言实现-Day2
c语言·算法·leetcode
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-15
论文阅读·人工智能·算法·搜索引擎·语言模型·自然语言处理
2401_857297913 小时前
招联金融内推(深圳武汉大量招后端、算法)---2025秋招内推
java·前端·算法·金融·求职招聘
非常规定义M3 小时前
Day30_0.1基础学习MATLAB学习小技巧总结(30)——优化工具箱及
开发语言·人工智能·学习·算法·数学建模·matlab
柠檬少少开发3 小时前
碎纸片的自动拼接复原技术
人工智能·算法·计算机视觉
2401_857297914 小时前
招联金融秋招内推喇--18薪
java·前端·算法·金融·求职招聘
larryyu_cs4 小时前
CF1494F Delete The Edges 题解
c++·算法·图论