蓝桥杯2023年-整数删除(链表,小根堆)

文章介绍了一种算法,利用小根堆和链表结构处理整数数列的删除操作,每次删除最小值后将相邻数加和,同时处理可能的数值溢出。代码展示了如何实现这个过程。
摘要由CSDN通过智能技术生成

题目描述

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

每次选择数列中最小的整数(如果最小值不止一个,选择最靠前的),将其删除。并把与它相邻的整数加上被删除的数值。输出 K 次操作后的序列。

思路

首先,多次删除的操作让我们可以想到可以使用链表。然后,取最小值的操作可以联想到使用小根堆。

然后就剩下了一个难点:如何表示每次删除数时给相邻数加上对应值。

因为小根堆不能更新已经存入在堆中的数据。所以我们在堆中只需要存储数据的val值与下标pos就行。取数据时根据所取得数据下标找到对应数据。

由于val值可能会变化,所以堆顶得数据不一定是目前的最小值,我们可以在链表结点上先标记增加值。然后在每次取最大值结点时判断一下是否存在增加值,如果有标记值,更新一下结点值,然后把结点重新存放回小根堆中。

(注意点:int可能会溢出,记得开long long)

代码

#include<bits/stdc++.h>
using namespace std;
#define pii pair<long long,int>
struct node{
    long long val;
    long long add;
    int l,r;
    bool st;
}nod[500005];
int main(){
    int n,k;
    priority_queue<pii,vector<pii>,greater<pii> >heap;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        long long v;cin>>v;
        nod[i]={v,0,i-1,i+1,0};
        heap.push({v,i});
    }
    while(k--){
        int pos=heap.top().second;heap.pop();
        while(nod[pos].add){
            nod[pos].val+=nod[pos].add;
            nod[pos].add=0;
            heap.push({nod[pos].val,pos});
            pos=heap.top().second;heap.pop();
        }
        int l=nod[pos].l;
        int r=nod[pos].r;
        nod[pos].st=1;
        long long val=nod[pos].val;
        nod[l].add+=val;
        nod[r].add+=val;
        nod[l].r=r;
        nod[r].l=l;
    }
    for(int i=1;i<=n;i++){
        if(!nod[i].st){
            cout<<nod[i].val+nod[i].add<<' ';
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值