当前位置: 首页 > news >正文

算法提升之-启发式并查集

今天给大家带来的是关于启发式的算法思想,这类型的题目对于大家的思维提升是有很大帮助的,首先需要先了解相关部分内容。

1.启发式合并的基本概念

2.启发式合并的相关部分

接下来我将通过几道例题来帮助大家更好地理解启发式合并的内容

题目一 修改数组

题目描述

给定一个长度为 N的数组A=[A1​,A2​,⋅⋅⋅,AN​],数组中有可能有重复出现的整数。

现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改A2​,A3​,⋅⋅⋅,AN​。

当修改 Ai时,小明会检查 Ai​ 是否在 A1 ∼ Ai−1中出现过。如果出现过,则小明会给 Ai​ 加上 1 ;如果新的 Ai仍在之前出现过,小明会持续给 Ai加 1 ,直 到 Ai没有在 A1Ai​−1 中出现过。

当 AN​ 也经过上述修改之后,显然 A 数组中就没有重复的整数了。

现在给定初始的 A 数组,请你计算出最终的 A数组。

输入描述

第一行包含一个整数 N。

第二行包含 N个整数 A1​,A2​,⋅⋅⋅,AN​。

其中,1≤N≤105,1≤Ai≤106。

输出描述

输出 N 个整数,依次是最终的A1​,A2​,⋅⋅⋅,AN​。

输入案例:

5
2 1 1 3 4

输出案例:

2 1 3 4 5

代码部分:

///修改数组-并查集
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e6 + 10;
int a[N], pre[N];
// root(i)为大于等于i,且在a[1~i-1]中没有出现过的数字int root(int x)
{return pre[x] = (pre[x] == x ? x : root(pre[x]));
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n;cin >> n;for (int i = 1; i <= n; ++i)cin >> a[i];// 初始化for (int i = 1; i <= 1e6; ++i)pre[i] = i;for (int i = 1; i <= n; ++i){cout << root(a[i]) << " ";a[i] = root(a[i]);                     // 要把a[i]变成转化后的a[i]再改根pre[root(a[i])] = pre[root(a[i] + 1)]; // 以为在这里a[i]已经出现了,所以root(a[i])要指向root(a[i]+1)}
}

这道题十分的巧妙,而处理这道题的关键就是要正确理解最后转移的部分pre[root(a[i])] = pre[root(a[i] + 1)];

问题描述

多米诺骨牌是一种玩具和游戏,由一组长方形的小方块组成,每个方块可分为两个部分,并在每个部分上标有从零到六或更多个点数。多米诺骨牌的长度通常是宽度的两倍。在游戏中,玩家将多米诺骨牌竖立并排成一行或一列,使相邻的骨牌的点数匹配。一旦某个骨牌被推倒,它会触发连锁反应,将相邻的骨牌推倒。

蓝蓝是一个有严重强迫症的大学生,是个完美主义者。他喜欢对称的形状,比如一个完美的圆形。他的手上有一副私人定制版多米诺骨牌,上面刻的不完全是数字,还有各种字符。这天,他突发奇想,如果严格按照多米诺骨牌的排放规则(相邻两骨牌只有一半相同的图案),能不能把它们放置成一个完整的首尾相接的圆形?

图片描述

输入格式

第 1 行:一个整数 N,代表骨牌的总数。

第 2到 N+1 行:每行有两个长度不超过 3 的字符串,代表骨牌上的刻的信息,字符串仅包含小写字母和标准数字键对应的可见字符。

输出格式

如果能产生一个符合题目要求的序列,则输出 YES,不能则输出 NO,对于无法预测的结果则输出 UNKOWN。

样例输入1

3
a b
b c
c a

样例输出1

Yes

样例输入2

3
aa b
b cc
cc z

样例输出2

No

代码部分:

#include <bits/stdc++.h>
using namespace std;
map<string,string>pre;
map<string,int>cnt;
string root(string a){return pre[a]=pre[a]==a?a:root(pre[a]);
}
void merge(string a,string b){if(root(a)==root(b))return;pre[root(a)]=root(b);
}
int main()
{int n;cin>>n;string s3;while(n--){string s1,s2;cin>>s1>>s2;s3=s2;if(pre.count(s1)==0)pre[s1]=s1;if(pre.count(s2)==0)pre[s2]=s2;merge(s1,s2);cnt[s1]++;cnt[s2]++;}
for(auto &[x,y]:cnt){if(y&1){cout<<"NO";return 0;}
}
string jug=root(s3);
for(auto &[x,y]:pre){
if(root(x)!=jug){cout<<"NO";return 0;
}
}
cout<<"YES";return 0;
}

这道题是非常经典的一道启发式的并查集问题,大家可以好好做做。

http://www.dtcms.com/a/321236.html

相关文章:

  • 剪映里面导入多张照片,p图后如何再导出多张照片?
  • VScode 文件标签栏多行显示
  • QML中显示二级界面的三种方式
  • 【Git】企业级使用
  • electron自定义国内镜像
  • 静电释放场景误报率↓78%!陌讯多模态融合算法在工业检测的落地优化
  • 【unity实战】用unity实现一个简易的战斗飞机控制器
  • BUG调试案例十七:ENC424J600以太网掉线问题案例
  • uniapp瀑布流最简单的实现方法
  • SonarQube 扫描多个微服务模块
  • 【51单片机2个按键控制流水灯转向】2022-10-25
  • 移动端开发中类似腾讯Bugly的产品推荐与比较-5款APP异常最终产品推荐-卓伊凡|bigniu
  • springBoot集成minio并实现文件的上传下载
  • 华为网路设备学习-28(BGP协议 三)路由策略
  • 怎么实现对三菱PLC的远程调试和PLC远程维护?
  • 【世纪龙科技】数智重构车身实训-汽车车身测量虚拟实训软件
  • 矩阵中的最长递增路径-记忆化搜索
  • 【ESP32-menuconfig(1) -- Build Type及Bootloader config】
  • Vue 项目安全设置方案:XSS/CSRF 防护指南
  • 浅谈:如何复现修复Bug?
  • OpenCV 3 终极指南:创建炫酷自定义窗口与图像显示的艺术
  • 【代码随想录day 14】 力扣 111.二叉树的最小深度
  • Cesium 无人机视角飞行漫游,截屏
  • RabbitMQ详情介绍—七种工作模式
  • springmvc4+hibernate4整合框架的搭建
  • 库函数版独立按键用位运算方式实现(STC8)
  • Array Description(Dynamic programming)
  • 【网络编程】IO多路转接——epoll
  • Java文件读写(IO、NIO)
  • 第39周——训练自己的数据集