题意:每一行输入一个编号,再给定它每一次出现的间隔时间,最后以“#”结束。之后是m次查询,根据他们出现的时间从早到晚把前m个编号打印出来,若在同一时间有多个编号,那么先输出小的编号。
思路:用优先队列维护时间点,每次堆中最小的输出,然后加上间隔再push进去即可。小于号重载的写法总是记不住,希望这次能够记住。两种写法:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <cstdlib> using namespace std; #define clc(s,t) memset(s,t,sizeof(s)) #define INF 0x3fffffff #define N 1005 struct node{ int id,t,num; bool operator<(const node &b) const { if(t == b.t) return id>b.id; return t>b.t; } }p[N]; priority_queue<struct node> h; int n,m; int main(){ int i = 0; char s[15]; while(scanf("%s",s) && strcmp(s,"#")){ scanf("%d %d\n",&p[i].id,&p[i].t); p[i].num = i; h.push(p[i++]); } scanf("%d",&m); while(m--){ struct node tmp = h.top(); printf("%d\n",tmp.id); h.pop(); tmp.t += p[tmp.num].t; h.push(tmp); } }
这样写也可以:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <cstdlib> using namespace std; #define clc(s,t) memset(s,t,sizeof(s)) #define INF 0x3fffffff #define N 1005 struct node{ int id,t,num; }p[N]; bool operator<(node a,node b){ if(a.t == b.t) return a.id>b.id; return a.t>b.t; } priority_queue<struct node> h; int n,m; int main(){ int i = 0; char s[15]; while(scanf("%s",s) && strcmp(s,"#")){ scanf("%d %d\n",&p[i].id,&p[i].t); p[i].num = i; h.push(p[i++]); } scanf("%d",&m); while(m--){ struct node tmp = h.top(); printf("%d\n",tmp.id); h.pop(); tmp.t += p[tmp.num].t; h.push(tmp); } }