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

交换瓶子问题

文章目录

前言

知道题目用暴力算法是可以过的,注意数据范围是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 种思路,图论的做法比较新奇,上述的结论也适合在其他类型的题目当中求解,后续还会更新图论相关的内容,喜欢的小伙伴可以点个关注啦

相关推荐
在路上看风景2 分钟前
19. 成员初始化列表和初始化对象
c++
uesowys7 分钟前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
zmzb010311 分钟前
C++课后习题训练记录Day98
开发语言·c++
ValhallaCoder14 分钟前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮16 分钟前
AI 视觉连载1:像素
算法
念风零壹43 分钟前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
智驱力人工智能1 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥2 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风2 小时前
代码随想录第十五天
数据结构·算法·leetcode
XX風2 小时前
8.1 PFH&&FPFH
图像处理·算法