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

news/2024/7/15 17:20:39 标签: 图论, 算法, 蓝桥杯, c++

交换瓶子问题

文章目录

  • 交换瓶子问题
    • 前言
    • 题目描述
    • 暴力解法【能过】
    • 图论解法
      • 知识预备【交换环】
    • 代码
    • 暴力做法和图论做法的对比
    • 总结

前言

知道题目用暴力算法是可以过的,注意数据范围是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

暴力解法【能过】

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

#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 步操作完成全部分解
现在我们只要求环的数量就行【类似于链表】 ,那么直接上代码

代码

解析都在代码注释当中呦

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


http://www.niftyadmin.cn/n/5028124.html

相关文章

Apache Commons Collections反序列化链分析(二)

Apache Commons是Apache开源的Java通用类项目在Java中项目中被广泛的使用&#xff0c;Apache Commons当中有一个组件叫做Apache Commons Collections&#xff0c;主要封装了Java的Collection(集合)相关类对象 通过接口实现查询&#xff0c;能获取到 ConstantTransformer、invo…

keepalived高可用学习 keepalived+nginx高可用负载均衡配置

文章目录 Keepalived1、概述2、配置文件说明3、简洁版配置过程4、keepalivedlvs配置5、主lvs不可用 可能性6、防止脑裂&#xff0c;解决方式7、keepalived的配置补充 keepalivednginx 高可用配置nginx的负载均衡nginx遇到的问题之负载均衡后获取客户端IPnginx配置中upstream的s…

黑马头条 后端项目部署_持续集成 Jenkins配置

项目部署_持续集成 1 今日内容介绍 1.1 什么是持续集成 持续集成&#xff08; Continuous integration &#xff0c; 简称 CI &#xff09;指的是&#xff0c;频繁地&#xff08;一天多次&#xff09;将代码集成到主干 持续集成的组成要素 一个自动构建过程&#xff0c; 从检出…

微信小程序自动化发布

参考:https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html 参考:https://www.npmjs.com/package/miniprogram-ci npm install miniprogram-ci -S上传文件 xx.js const isNodeJs typeof process ! undefined && process.release ! null &&…

LeetCode【3. 无重复字符的最长子串】

工欲善其事必先利其器 题目&#xff1a;给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 public int lengthOfLongestSubstring(String s) {int n s.length();int[] charIndex new int[128]; // 用于存储字符的索引&#xff0c;ASCII字符集共有…

Java面试八股文宝典:初识数据结构-数组的应用扩展之ConcurrentHashMap

在之前的文章中&#xff0c;我们深入了解了 HashMap 和 HashTable 的底层代码原理&#xff0c;包括它们的数据结构和工作原理。在本章中&#xff0c;我们将继续探讨 ConcurrentHashMap、HashSet 和 LinkedHashMap 这些与 HashMap 有关的关键数据结构&#xff0c;深入了解它们的…

埃文科技受邀出席“安全堤坝”技术论坛

2023年9月11日&#xff0c;2023年国家网络安全宣传周河南省活动开幕式暨河南省网络文明大会在开封博物馆开幕。由CCF YOCSEF郑州举办的“聚焦数据交易监管技术&#xff0c;筑牢数据交易‘安全堤坝’”技术论坛在开封市博物馆二楼会议厅举行。埃文科技总经理王永博士与副总经理武…

Ceph入门到静态-deep scrub 深度清理处理

9.6 洗刷 REPORT DOCUMENTATION BUG# 除了为对象创建多个副本外&#xff0c;Ceph 还可通过洗刷归置组来确保数据完整性&#xff08;请参见第 1.3.2 节 “归置组”了解有关归置组的详细信息&#xff09;。Ceph 的洗刷类似于在对象存储层运行 fsck。对于每个归置组&#xff0c;C…