典型题目
优先队列
对于蒟蒻来说,堆之类的……实在是有点不好理解。
所以我们今天只从表面上讲讲什么是优先队列,并且争取做到熟练的运用(知其然不知其所以然)
就好了。
什么是优先队列?
我们可以简单粗暴的理解为优先队列和普通队列差不多,但是多了一个自动的排序,而这个排序规则,你自己定。
我们最常用到的升序和降序排序,如下:
//升序队列
priority_queue<数据类型,vector<数据类型>,greater<数据类型> >Greatq;
//降序队列
priority_queue<数据类型,vector<数据类型>,less<数据类型> >Lessq;
前期的话对于蒟蒻来说,这两个已经够了,不过后期如果有更复杂的排序规则,可以自己将运算符重载……
易错点
- 注意这句话:
priority_queue<数据类型,vector<数据类型>,greater<数据类型> >Greatq;
^ //注意这里,两个 > 不能连一块,不然会被当成位运算,不管是升序还是降序。
- 自动排序的意思是指:每次往队列里扔一个东西,都会自动按规则排序一次。
基本操作
优先队列的基本操作……和普通队列差不多,但是有一些出现了差别:
priority_queue<int,vector<int>,greater<int> >q;
int a;
cin>>a;
q.push(a);//这个都能理解吧,往队列里扔一个数
cin>>a;
q.push(a);//这个此时,由于有了两个元素,队列自动按我们设定好的升序排序
a=q.top();//注意这个top虽说是返回队头元素,但是可能已经不是原先那个队头!可能是排序后的队头元素!
q.pop();//pop,挤出来的也不一定是最先进队的元素,而是排序后的第一个元素。
cout<<a;
a=q.top();//同上
q.pop();
cout<<q.size();//返回队q元素个数
cout<<q.empty();//返回q是否为空,空则返回1,否则返回0
回头看题
题目传送门
这题简直就是优先队列的板子题。
实际上就是让我们创建一个升序队列,每次从里面pop两个,累加到ans上,然后把这两个的和在扔进队里。
常数不大,稳过。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,t,a1,a2,ans;
priority_queue<int,vector<int>,greater<int> >q;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&t);
q.push(t);
}
for(int i=1;i<n;i++){
a1=q.top();
q.pop();
a2=q.top();
q.pop();
ans+=a1+a2;
q.push(a1+a2);
}
printf("%d",ans);
return 0;
}
完结撒花