题目大意:
一个数据流是一种实时的、连续的、有序的数据项。数据流中的内容可以包含传感器数据、英特网流量、金融欺诈、网络拍卖、诸如网页访问记录或电话记录等的事物记录数据。可以在这种动态数据流上建立查询,每个一段时间查询一次并返回相应的结果,例如一个工厂仓库的温度探测系统可以这样建立查询:
每隔5分钟返回一次过去5分钟的内的最高温度;
返回过去10分钟内每隔楼层的平均温度;
现需要开发一个类似的数据流查询系统Argus,用户可以通过该系统对数据流建立查询,并按照其想要的时间间隔不断返回相应的结果,比如可以建立如下查询:
Register Q_num Period
其中Register表示向系统登记查询命令,Q_num为查询的ID号(Q_num ≤ 3000,各ID号不相同),Period为查询的时间间隔(Period ≤ 3000);
现有多个这样的查询,待登记完毕所有查询后,系统将同时执行所有的命令,现要求前K(K为正整数,K ≤ 10,000)个返回结果的查询ID号,若有多个查询在同一时间点返回结果,则先输出ID号小的那个。
注释代码:
/*
* Problem ID : POJ 2051 Argus
* Author : Lirx.t.Una
* Language : C
* Run Time : 16 ms
* Run Memory : 156 KB
*/
#include <stdio.h>
//maximum number of query,最大查询个数
//最大数为3000,单堆数组中的首个元素不放元素
//下标0可以方便判断指针偏移时是否到达终点(插入操作时)
#define MAXQUERYN 3001
//命令最大长度为Register的8位,最后一位留给空字符
#define MAXCMDLEN 9
//对两个查询进行大小比较
//第一种情况是前者的返回时间大于后者
//第二种情况是前者的返回时间等于后者,但前者的ID号大于后者
#define cmp(x,y) ( (x)->t != (y)->t ? (x)->t - (y)->t : (x)->id - (y)->id )
struct Node;
typedef struct Node Query_body;
typedef struct Node * Query;
struct Node {//查询结点
int id;
int p;
int t;
};
Query_body qb[MAXQUERYN];//query body,查询体的数组,用于保存查询本身的数据
Query q[MAXQUERYN];//查询二叉堆数组,用于存放查询的指针(指针空间比),
//指针占用空间比查询体小很多,在赋值等操作中可以节省时间
int sz;//堆的大小,在插入过程中需要动态增加
char cmd[MAXCMDLEN];
void
push(Query eq) {//入堆操作,element query,带插入的查询
int n;//none pointer,空穴位置指针
int f;//father pointer of none,空穴的父结点的位置指针
for ( n = ++sz;//先对堆的大小进行拓展,并将空指针指向拓展出来的空穴
( f = n >> 1 ) && cmp( q[f], eq ) > 0;//若空穴的父结点指针上达0则表示已
//偏移到了尽头,可以直接退出循环
//同时父结点必须大于待插入结点时才可以将父结点移
//入空穴内
n = f /*移动后,父结点成为了新的空穴,空穴指针要向上偏移*/ )
q[n] = q[f];//将父结点移入空穴内
q[n] = eq;//将待插入结点覆盖到空穴中完成插入工作
}
void
down(void) {//将堆顶的返回时间进行更新,跟新后向下调整其位置
Query eq;
int n;//none pointer
int c;//child pointer of none,空穴的孩子的位置指针
eq = q[1];
printf("%d\n", eq->id);//取堆顶查询输出其ID号
eq->t += eq->p;//更新其返回时间
for ( n = 1;//输出后相当于堆顶元素出堆,即堆顶为空,需要向下调整挪出合适
//的位置给更新过的出堆元素
( c = n + n ) <= sz;//c先指向空穴的左儿子,若左儿子都没就意味着
//其没有儿子了,即已经偏移到了堆底,到了尽头,可以退出循环
n = c /*移动后儿子成为新的空穴,空穴指针需向下偏移*/) {
//如果空穴还有右儿子,则使c指向较小的右儿子
if ( c < sz && cmp( q[c + 1], q[c] ) < 0 )
c++;
if ( cmp( q[c], eq ) > 0 )//若出堆元素比空穴儿子还小则可以直接退出循环
//将出堆元素覆盖给空穴
break;
else
q[n] = q[c];//否则空穴下移
}
q[n] = eq;//将出堆元素覆盖到空穴处完成一次向下调整
}
int
main() {
int k;
int i;
sz = 0;
for ( i = 1; scanf("%s", cmd), *cmd != '#'; i++ ) {
scanf("%d%d", &qb[i].id, &qb[i].p);
qb[i].t = qb[i].p;
push( qb + i );
}
scanf("%d", &k);
while ( k-- )
down();
return 0;
}
无注释代码:
#include <stdio.h>
#define MAXQUERYN 3001
#define MAXCMDLEN 9
#define cmp(x,y) ( (x)->t != (y)->t ? (x)->t - (y)->t : (x)->id - (y)->id )
struct Node;
typedef struct Node Query_body;
typedef struct Node * Query;
struct Node {
int id;
int p;
int t;
};
Query_body qb[MAXQUERYN];
Query q[MAXQUERYN];
int sz;
char cmd[MAXCMDLEN];
void
push(Query eq) {
int n;
int f;
for ( n = ++sz; ( f = n >> 1 ) && cmp( q[f], eq ) > 0; n = f )
q[n] = q[f]
q[n] = eq
}
void
down(void) {
Query eq;
int n;
int c;
eq = q[1];
printf("%d\n", eq->id)
eq->t += eq->p
for ( n = 1; ( c = n + n ) <= sz; n = c ) {
if ( c < sz && cmp( q[c + 1], q[c] ) < 0 )
c++;
if ( cmp( q[c], eq ) > 0 )
break;
else
q[n] = q[c];
}
q[n] = eq;
}
int
main() {
int k;
int i;
sz = 0;
for ( i = 1; scanf("%s", cmd), *cmd != '#'; i++ ) {
scanf("%d%d", &qb[i].id, &qb[i].p);
qb[i].t = qb[i].p;
push( qb + i );
}
scanf("%d", &k);
while ( k-- )
down();
return 0;
}
STL priority_queue:
/*
* Problem ID : POJ 2051 Argus
* Author : Lirx.t.Una
* Language : C++
* Run Time : 16 ms
* Run Memory : 208 KB
*/
#include <iostream>
#include <cstdio>
#include <queue>
#define MAXCMDLEN 9
using namespace std;
struct Qry {
int id;
int p;
int t;
Qry(void) {}
Qry( int xid, int xp, int xt ) :
id(xid), p(xp), t(xt) {}
bool
operator<(const Qry &oth)
const {
if ( t != oth.t )
return t > oth.t;
else
return id > oth.id;
}
};
char cmd[MAXCMDLEN];
int
main() {
int id, p;
int k;
Qry q;
priority_queue<Qry> heap;
while ( scanf("%s", cmd), *cmd != '#' ) {
scanf("%d%d", &id, &p);
heap.push( Qry( id, p, p ) );
}
scanf("%d", &k);
while ( k-- ) {
q = heap.top();
heap.pop();
q.t += q.p;
printf("%d\n", q.id);
heap.push(q);
}
return 0;
}
单词解释:
Argus:人名,希腊神话中的百眼巨人
stream:n, 流,溪流
real-time:adj, 实时的,接到指示立即执行的
continuous:adj, 连续不断的
ordered:adj, 有序的
item:n, 项目,条款,物件
sensor:n, 传感器
traffic:n, 交通,通信量
Internet traffic:n, 英特网通信量
financial:adj, 金融的,财政的
tricker:n, 欺诈者
auction:n, 拍卖
transaction:n, 交易
log:n, 记录,日志
transaction log:n, 交易记录
likewise:adv, 同样地(句首)
query:n, vt, 查询
query over...:vt, 在...上查询
increment:n, 增量
incrementally:adv, 递增地
detection:n, 探测
warehouse:n, 仓库
retrieve:vt, 取回,检索
register:vt, 注册,登记
corresponding:adj, 相应的
desired:adj, 渴求,渴望的,想得到的
instruction:n, 命令,指令
interval:n, 间隔
consecutive:adj, 连贯的,连续的
comfirm:vt, 确认
It is confirmed that..:可以确定的是....
ascending:adj, 上升的,升序的
descending:adj, 下降的,降序的
exceed:vt, 超过