任务系统
蒜头君设计了一个任务系统。这个系统是为了定时提醒蒜头君去完成一些事情。
系统大致如下,初始的时候,蒜头君可能会注册很多任务,每一个任务的注册如下:
Register Q_num Period
表示从系统启动开始,每过 Period 秒提醒蒜头君完成编号为Qnum 的任务。
你能计算出蒜头君最先被提醒的 k 个任务吗?
输入格式
第一行输入 n(0<n≤50000),k(0<k≤10000),其中 n 表示蒜头君注册的任务数量。
接下来 n 行,每行输入一条注册命令,其中0<qnum≤3000,0≤Period≤3000。
输出格式
顺序输出 k 行,表示依次提醒的任务的编号。如果同一时间有多个任务,最先提醒编号小的任务。
样例输入复制
2 5
Register 2004 200
Register 2005 300
样例输出复制
2004
2005
2004
2004
2005
思路:优先队列实现
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
struct task{
int num;
int period;
int t;
bool operator <(const task other) const{
if(t != other.t){
return t > other.t;
}
else
return num > other.num;
}
};
priority_queue<task> pq;
int main(){
int n,k;
int tnum,tperiod;
task tmp;
string s;
cin >> n >> k;
while(n--){
cin >> s >> tnum >> tperiod;
tmp.num = tnum;
tmp.period = tperiod;
tmp.t = tmp.period;
pq.push(tmp);
}
while(k--){
tmp = pq.top();
pq.pop();
cout << tmp.num << endl;
tmp.t += tmp.period;
pq.push(tmp);
}
return 0;
}
n个最小和
给出两个包含 n 个整数的数组 A,B。分别在 A, B 中任意出一个数并且相加,可以得到 n^2 个和。求这些和中最小的 n 个。
输入格式
输入第一行一个整数 n(1≤n≤50000)。
接下来一行输入数组 A,用空格隔开。
接下来一行输入数组 B,用空格隔开。
1≤Ai,Bi≤10^9
输出格式
从小到大输出最小的 n 个和,用空格隔开。
样例输入复制
4
1 3 5 7
2 4 6 8
样例输出复制
3 5 5 7
#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int aa[50002],bb[50002];
struct node{
int a;
int b;
int sum;
bool operator <(const node other) const{
return sum > other.sum;
}
};
priority_queue<node> pq;
int main(){
int n ;
cin >> n;
for(int i = 0;i < n;i++){
cin >> aa[i];
}
for(int i = 0;i < n;i++){
cin >> bb[i];
}
sort(aa,aa+n,less<int>());
sort(bb,bb+n,less<int>());
for(int i = 0;i < n;i++){
node tmp;
tmp.a = i;
tmp.b = 0;
tmp.sum = aa[i] + bb[0];
pq.push(tmp);
}
for(int i = 0;i < n;i++){
node t = pq.top();
pq.pop();
if(!i){
cout << t.sum;
}
else{
cout << " " << t.sum;
}
t.b++;
t.sum = aa[t.a] + bb[t.b];
pq.push(t);
}
return 0;
}
银行的客户队列
某个银行很傲娇,来了一些客户,有时先接待优先级最高的客户,有时先接待优先级最低的客户,有如下四种操作:
0:系统停止服务。
1 K P:增加一个 ID 为 K(K≤106) 的客户,其优先级是 P(P≤107)。
2:查询优先级最高的客户,接待他,并从等候队列里删除。
3:查询优先级最低的客户,接待他,并从等候队列里删除。
你的任务是依次输出这些客户的 ID。
输入格式
若干行,以 0 结束(总操作数不超过 10^5)。
一个客户可能访问多次;保证在任意时刻,队列中的优先级各不相同。
输出格式
对于 2 和 3 操作,一行一个整数表示 ID,若查询无结果,则输出 0。
样例输入复制
2
1 20 14
1 30 3
2
1 10 99
3
2
2
0
样例输出复制
0
20
30
10
0
思路:stl中的set会自动排序
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <queue>
#include <set>
using namespace std;
set<pair<int,int> > q;
//pair按第一维排序从小到大,再按第二维从小到大
int main(){
int op,k,p;
set<pair<int,int> >::iterator it;
while(cin >> op && op){
if(op == 1){
cin >> k >> p;
q.insert(make_pair(p,k));
}
else if(op == 2){
if(q.empty()){
cout << 0 << endl;
}
else{
it = q.end();
it--;
cout << it->second << endl;
q.erase(it);
}
}
else{
if(q.empty()){
cout << 0 << endl;
}
else{
it = q.begin();
cout << it->second << endl;
q.erase(it);
}
}
}
return 0;
}