蓝桥杯整数删除(优先队列&&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;表示从大到小排列;

自定义排序:

相关推荐
tt5555555555556 分钟前
每日一题——滑动窗口的最大值
c语言·数据结构·算法·leetcode·八股文
眼镜哥(with glasses)25 分钟前
蓝桥杯python基础算法(2-2)——基础算法(D)——进制转换*
算法
和风化雨38 分钟前
排序算法--选择排序
c语言·c++·算法·排序算法
和风化雨42 分钟前
排序算法--桶排序
c语言·数据结构·c++·算法·排序算法
董董灿是个攻城狮2 小时前
DeepSeek-R1 技术报告精华整理:通过强化学习提升大模型推理能力
算法
小姚也要变强2 小时前
sort排序 计数排序 map set C++ 蓝桥杯
开发语言·c++·算法·蓝桥杯
WBluuue2 小时前
大一计算机的自学总结:数据结构设计相关题
数据结构·c++·算法·leetcode·链表
白白糖2 小时前
Day 28 卡玛笔记
python·算法·力扣
JNU freshman2 小时前
蓝桥杯思维训练营(四)
算法·蓝桥杯
BingLin-Liu2 小时前
蓝桥杯备考:前缀和算法之最大子段和
算法