优先队列的基本操作
queue<int>vis;
vis.push();//插入有序队列
vis.pop();//删除队首
vis.top();//取队首
vis.empty()==1;//判断队列为空
int n=vis.size();//得到队列的大小
priority_queue<int ,vector<int>,less<int> >vis;//从大到小
priority_queue<int ,vector<int>,greater<int> >vis;//从小到大
//不需要再定义一次queue<int>vis;
//sort(a,a+n+1,greater<int>());和sort的用法有点像
struct node{
int x,num;
};
bool operator < (const node &s1,const node &s2)
{
if(s1.x!=s2.x) return s1.x>s2.x;//从小到大
return s1.num>s2.num;
}
nefu 1688 合并果子-优先队列
思路:
先合并小的数消耗的总体力最小
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> >vis;//从小到大
int main()
{
int n,x,s1,s2,ans=0;//n种果子,s1为排序后的第一堆,s2为第二堆
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
vis.push(x);
}
while(vis.size()>1)
{
s1=vis.top();
vis.pop();
s2=vis.top();
vis.pop();
ans=ans+s1+s2;
vis.push(s1+s2);
}
printf("%d",ans);
return 0;
}
nefu 1691 瑞瑞的木板-优先队列
思路:
逆向思维后与合并果子一样
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> >vis;//从小到大
int main()
{
int n,x,s1,s2,ans;
while(cin>>n)
{
ans=0;
for(int i=1; i<=n; i++)
{
cin>>x;
vis.push(x);
}
while(vis.size()>1)
{
s1=vis.top();
vis.pop();
s2=vis.top();
vis.pop();
ans+=s1+s2;
vis.push(s1+s2);
}
vis.pop();
printf("%d\n",ans);
}
return 0;
}
nefu 1537 买饭-优先队列
思路:
为了让等待的时间最短,让接水时间长的人后接,所以从小到大排列。平均等待时间是每个人的等待时间相加再除以人数。因为既要用到时间,还要输出排序后的原下角标,所以构建一个结构体。
#include <bits/stdc++.h>
using namespace std;
struct node
{
int time,num;
};
bool operator < (const node &s1,const node &s2)
{
if(s1.time!=s2.time)return s1.time>s2.time;
return s1.num>s2.num;
}
//定义一个函数返回时间短的人,时间相同时返回下角标小的
priority_queue < node,vector<node> >vis;
int main()
{
ios::sync_with_stdio(false);
int n,x;
double sum=0,ans=0;
//tim记录当前人的等待时间,ans记录等待时间总和
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
vis.push({
x,i});
}
while(!vis.empty())
{
node tmp=vis.top();
vis.pop();
ans+=sum;
sum+=1.0*tmp.time;
vis.empty()?printf("%d\n",tmp.num):printf("%d ",tmp.num);
}
printf("%.2lf\n",ans/(1.0*n));
return 0;
}
nefu 1692 堆-优先队列
思路:
类似丑数,每次取最小的数发展,就能找出所有构成blash数集的数
#include <bits/stdc++.h>
using namespace std;
priority_queue <int,vector<int>,greater<int> >vis;
int main()
{
ios::sync_with_stdio(false);
int n,x,ch;//ch控制选择进行的指令,x为需要进行执行的数字
cin>>n;//执行5次
for(int i=1;i<=n;i++)
{
cin>>ch;
if(ch==1) {
cin>>x; vis.push(x);}
if(ch==2) printf("%d\n",vis.top());
if(ch==3) vis.pop();
}
return 0;
}
nefu 1690 桐桐的新闻系统-优先队列
思路:
实际上就是将第一种时间的n倍第二种时间的m倍排序后,将对应时间的id输出即可,所以要将时间与id还有累计时间搞成结构体
#include <bits/stdc++.h>
using namespace std;
char s[30];
int id,tim,k;
struct node
{
int time,sum,id;
};
bool operator < (const node &s1,const node &s2)
{
if(s1.sum!=s2.sum) return s1.sum>s2.sum;
return s1.id>s2.id;
}
priority_queue <node,vector<node> >vis;
int main()
{
ios::sync_with_stdio(false);
while(cin>>s&&s[0]!='#')
{
cin>>id>>tim;
vis.push({
tim,tim,id});
}
cin>>k;
while(k--)
{
node tmp=vis.top(); vis.pop();
printf("%d\n",tmp.id);
vis.push({
tmp.time,tmp.sum+tmp.time,tmp.id});
}
return 0;
}
nefu 1689 序列合并-优先队列
思路:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+10;
int a[N],b[N];
struct node
{
int x,y;
ll sum;
};
bool operator < (const node &s1,const node &s2)
{
return s1.sum>s2.sum;
}
priority_queue<node,vector<node> >vis;
int main()
{
ios::sync_with_stdio(false);
int n,x;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
}
for(int i=1;i<=n;i++)
{
vis.push({
i,1,a[i]+b[1]});
}
for(int i=1;i<=n;i++)
{
node tmp=vis.top();
printf("%d\n",tmp.sum);
vis.pop();
int x=tmp.x;
int y=tmp.y;
vis.push({
x,y+1,a[x]+b[y+1]});
}
return 0;
}