蓝桥杯整数删除(优先队列&&pair,模拟链表)

题目:给定一个长度为 N 的整数数列:A1, A2, ... , AN。你要重复以下操作 K 次:

每次选择数列中最小的整数(如果最小值不止一个,选择最靠前的),将其删除。

并把与它相邻的整数加上被删除的数值。

输出 K 次操作后的序列。

第一行包含两个整数 N 和 K。

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

对于 20% 的数据,1 ≤ K < N ≤ 10000。

对于 100% 的数据,1 ≤ K < N ≤ 5 × 1e5,0 ≤ Ai ≤ 1e8。

输入

5 3
1 4 2 8 7

输出

17 7

暴力:for循环找最小值,o(n**2)超了,用vector删除优点是不需要模拟链表的删除过程,不需要实时记录被删除的数的索引,(注意min值是要在每个K循环之前都要更新的,呜呜,一开始我在循环外更新,就出错了,找了好久才发现错因)

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define N 0x3f3f3f3f
#define int long long
int n,k;
vector<int> v(5e5);
signed main()
{
	cin>>n;
	cin>>k;
	for(int i=0;i<n;i++)
	{
		cin>>v[i];
	}
	int e=n;
	int x=0;
	while (k--)
	{
        int min=N;
		for(int i=0;i<e;i++)
		{
			if(min>v[i]) 
			{
				min=v[i];
			    x=i;
			}
		}
	    v[x-1]+=v[x];
		v[x+1]+=v[x];
		v.erase(v.begin()+x);
		e--;
	} 
	for(int i=0;i<e;i++)
	{
		cout<<v[i]<<" ";
	}
	cout<<endl;
	return 0;
}

优化: 模拟链表(便于删除中间节点):需要左右两个指针链接各个节点

优先队列:便于找到最值并且出队,相当于逻辑上删除该数下次不再比较这个数,但是缺点是不能实时更新//由于每删除一个数,其两边相邻数都要+1,因此,priority_queue里的数不一定是实时的,所以需要引入st[]存储更新,且在每次输出最小值时都要比较一下

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N = 5e5 + 10;
int st[N], l[N], r[N];

signed main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n, k; cin >> n >> k;
	priority_queue<pii, vector<pii>, greater<pii>>q;
	for(int i = 0; i < n; i ++)
	{
		cin >> st[i];
		q.push({st[i], i});
        l[i] = i - 1;//模拟链表,链接左右两侧节点 
		r[i] = i + 1;
		if(r[i] == n)
			r[i] = -1;
	}

	int cnt = k;
	while(k)
	{
		pii t = q.top();
        q.pop();

		if(t.first != st[t.second])
		{
			q.push({st[t.second], t.second});
			continue;
		}

		k --;
        int pos = t.second;
        //将该元素的相邻元素加上该数值
		if(l[pos] >= 0)
		    st[l[pos]] += t.first;
        if(r[pos] >= 0)
		    st[r[pos]] += t.first;
			//更新相邻点的相邻元素,模拟链表删除元素 
		if(l[pos] >= 0)
		    r[l[pos]] = r[pos];
		if(r[pos] >= 0)
		    l[r[pos]] = l[pos];
        //该元素已经被删除,打标记,方便最后输出结果 
		st[pos] = -1;
	}
	for(int i = 0; i < n; i ++)
	{
		if(st[i] != -1)
			cout << st[i] << " ";
	}
	cout << endl;
	return 0; 
}

优先队列:

priority_queue<pii, vector<pii>, greater<pii>>q;这里明确指出了vector是优先队列的底层容器,且存储的元素类型是pii,对于pair类型,greater<pii>是首先比较第一个元素,如果不同,则按照第一个元素排序,如果相同,则比较第二个元素。

priority_queue<数据类型> q; 默认是大顶堆,即从大到小排列;

priority_queue<数据类型,vector<数据类型>,greater<数据类型>> q;表示从大到小排列;

自定义排序:

相关推荐
豆豆酱22 分钟前
Informer方法论详解
算法
槐月初叁26 分钟前
多模态推荐系统指标总结
算法
迪小莫学AI42 分钟前
LeetCode 2588: 统计美丽子数组数目
算法·leetcode·职场和发展
昂子的博客1 小时前
热门面试题第十天|Leetcode150. 逆波兰表达式求值 239. 滑动窗口最大值 347.前 K 个高频元素
算法
卑微小文2 小时前
2025国内网络反爬新高度:代理IP智能轮换算法揭秘
后端·算法·架构
ChinaRainbowSea2 小时前
MySQL 索引的数据结构(详细说明)
java·数据结构·数据库·后端·mysql
白晨并不是很能熬夜3 小时前
【JVM】字节码指令集
java·开发语言·汇编·jvm·数据结构·后端·javac
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧3 小时前
C语言_数据结构总结7:顺序队列(循环队列)
c语言·开发语言·数据结构·算法·visualstudio·visual studio
橘颂TA3 小时前
每日一练之合并两个有序链表
数据结构·链表
LIUJH12333 小时前
数据结构——单调栈
开发语言·数据结构·c++·算法