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

P8686 [蓝桥杯 2019 省 A] 修改数组--并查集 or Set--lower_bound()的解法!!!

P8686 [蓝桥杯 2019 省 A] 修改数组--并查集

    • 题目
  • 并查集解析
    • 代码【并查集解】
  • Set 解法解析
    • lower_bound
    • 代码

题目

在这里插入图片描述

并查集解析

首先先让所有的f(i)=i,即每个人最开始的祖先都是自己,然后就每一次都让轮到那个数的父亲+1(用过后的标记),第二次出现的时候就直接用父亲替换掉

并查集的作用:并查集用于快速查找元素的根节点,并进行路径压缩以提高效率。

并查集适用场景

1.快速合并与查询:需要频繁合并集合(如标记某个数已被占用)和查询根节点(找下一个可用位置)。
2.路径压缩优化:通过压缩查找路径,使得后续查询接近常数时间复杂度。
3.动态维护连续区间:每个数字的父节点指向下一个可用位置,天然维护了一个动态递增的区间。

代码【并查集解】

#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <queue>
#include <climits>  // 包含INT_MAX常量
#include <cctype>
using namespace std;
int n, f[100010];

int find(int x) {
	if (f[x] == x)
		return x;
	return f[x] = find(f[x]);
}

int main() {
	cin >> n;
	for (int i = 1; i <= 1e5; i++)
		f[i] = i;
	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;
		x = find(x);
		cout << x << ' ';
		f[x] += 1;//为下一次重复做准备
	}
	return 0;
}

Set 解法解析

这道题我们可以利用set 的有序性和高效查找特性,直接找到每个元素的最小可用值

代码思路:
先将1~1e6的值依次存入set中,然后利用lower_bound()找到第一个大于等于x的值,使用过后再利用erase()删除
【这个代码的思路完全符合我们脑中所想】

lower_bound

是一个用于在有序序列中【有序序列set】查找特定元素的函数。它返回指向第一个不小于给定值的元素的迭代器。结合set(有序集合),可以高效解决需要动态维护有序数据并快速查找的问题。

lower_bound 的核心功能
1.作用:在有序序列中找到第一个不小于目标值的位置。
2.返回值:
i 如果存在符合条件的元素,返回指向该元素的迭代器。
ii如果所有元素都小于目标值,返回容器的end()迭代器。

在 set 中使用 lower_bound
set 的特性:
1.元素唯一且按升序自动排序。
2.插入、删除和查找操作的时间复杂度为 O(log N)。
调用方式:

auto it = s.lower_bound(x);  // it 是迭代器,指向第一个 >=x 的元素
cout << *it;                 // *it 是该元素的实际值
s.erase(it);                 // 直接传递迭代器删除元素(不需要 *)

lower_bound 下界 & upper_bound上界
在这里插入图片描述

为什么不用 vector 替代 set?
vector 的插入、删除和查找效率较低,适合静态数据。

vector 的查找必须遍历或使用 find 算法,效率低。

代码

#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <queue>
#include <climits>  // 包含INT_MAX常量
#include <cctype>
using namespace std;
int n;
set<int> s;

int main() {
	cin >> n;
	for (int i = 1; i <= 1e6; i++)
		s.insert(i);
	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;
		auto a = s.lower_bound(x); 
	//lower_bound返回第一个大于等于x的值,在有序集合set中能完美解决该问题
		cout << *a << ' ';
		s.erase(a);
	}
	return 0;
}

相关文章:

  • 设计模式 一、软件设计原则
  • Spring源码探析(二):BootstrapContext初始化深度解析(默认配置文件加密实现原理)
  • [算法笔记]cin和getline的并用、如何区分两个数据对、C++中std::tuple类
  • uniapp版本加密货币行情应用
  • Unity DOTS从入门到精通之EntityCommandBufferSystem
  • C#模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹
  • 【vitepress】如何搭建并部署自己的博客网站
  • sqlserver中的锁模式 | SQL SERVER如何开启MVCC(使用row-versioning)【启用行版本控制减少锁争用】
  • 基于单片机的智慧农业大棚系统(论文+源码)
  • mysql(community版)压缩包安装教程
  • 【计算机网络】确认家庭网络是千兆/百兆带宽并排查问题
  • 解决电脑问题(5)——鼠标问题
  • Android SharedPreferences 工具类封装:高效、简洁、易用
  • MySql数据库增删改查常用语句命令-MySQL步骤详解教程
  • Docker 的基本概念和优势,以及在应用程序开发中的实际应用
  • (十七) Nginx解析:架构设计、负载均衡实战与常见面试问题
  • windows环境下安装部署dify+本地知识库+线上模型
  • linux安装reids
  • 探索在直播中的面部吸引力预测新的基准和多模态方法
  • Git基础之分支
  • 浙江首个核酸药谷落子杭州,欢迎订阅《浪尖周报》第23期
  • 同济大学原常务副校长、著名隧道及地下工程专家李永盛逝世
  • 一生要出片的年轻人,买爆相机
  • 观察|天空之外的战场:官方叙事、新闻与社交平台中的印巴冲突
  • 上海劳模风采馆焕新升级后重新开放,展示480位劳模先进故事
  • 巴西总统卢拉将访华