题目:给定一个长度为 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;表示从大到小排列;
自定义排序: