清華OJ——數據結構與算法實驗(中國石油大學)
Description
A HPS cluster is equipped with a unique task scheduler. To be simple, it is assumed that this cluster doesn’t support multiple tasks running at the same time, such that only one task is allowed to be in running state at any moment. Initially, the priority of ever task is denoted by an integer which is called priority number. The smaller priority number stands for high priority. If two tasks have same task number, the priority is decided in the ASCII order of task name. Following this policy, resources, such as CPU, are always occupied by the task with minimum priority number. When one task is finished, the one with minimum priority number in the rest tasks is picked to execute. The finished task won’t quit immediately. The priority number is doubled and put back to the task set. Once the priority number is greater or equal to 2^32, this task is deleted from the task set.
Given initial priority setting of every task, your job is to predict the running order of a batch of tasks.
Input
First line contains two integers, says n and m. n stands for the number of tasks in initial state. m stands for the length of predicted sequence. Every line is ended by a line break symbol. In each one of the following n lines, an integer and a string are included. This string is shorter than 8, which only contains lowercase letters and numbers. The integer is priority number and the string is the task name. The integer and string is separated by space.
Output
At most m lines, each one contains a string. Output the name of tasks according to the order that tasks are executed. If the number of executed tasks is less than m, then output all the executed tasks.
Example
Input
3 3
1 hello
2 world
10 test
Output
hello
hello
world
Restrictions
0 <= n <= 4,000,000
0 <= m <= 2,000,000
0 < Initial priority number < 2^32
No tasks have same name
Time: 2 sec
Memory: 512 MB
Hints
Priority queue
描述
某高性能計算集群(HPC cluster)采用的任務調度器與眾不同。為簡化起見,假定該集群不支持多任務同時執行,故同一時刻只有單個任務處於執行狀態。初始狀態下,每個任務都由稱作優先級數的一個整數指定優先級,該數值越小優先級越高;若優先級數相等,則任務名ASCII字典順序低者優先。此后,CPU等資源總是被優先級數最小的任務占用;每一任務計算完畢,再選取優先級數最小下一任務。不過,這里的任務在計算結束后通常並不立即退出,而是將優先級數加倍(加倍計算所需的時間可以忽略)並繼續參與調度;只有在優先級數不小於2^32時,才真正退出
你的任務是,根據初始優先級設置,按照上述調度原則,預測一批計算任務的執行序列。
輸入
第一行為以空格分隔的兩個整數n和m,n為初始時的任務總數,m為所預測的任務執行序列長度,每行末尾有一個換行符
以下n行分別包含一個整數和一個由不超過8個小寫字母和數字組成的字符串。前者為任務的初始優先級數,后者為任務名。數字和字符串之間以空格分隔
輸出
最多m行,各含一個字符串。按執行次序分別給出執行序列中前m個任務的名稱,若執行序列少於m,那么輸出調度器的任務處理完畢前的所有任務即可。
樣例
見英文題面
限制
0 ≤ n ≤ 4,000,000
0 ≤ m ≤ 2,000,000
0 < 每個任務的初始優先級 < 2^32
不會有重名的任務
時間:2 sec
內存:512 MB
提示
優先級隊列
#include <cstdio> #include<iostream> #include<cstring> #define N 4000050 using namespace std; struct ss { long long x; char y[10]; bool operator < (const ss &s)const { if(x!=s.x)return x>s.x; if(strcmp(y,s.y)>0)return 1; else return 0; } }; class heap { private: ss arr[N]; int sum_element; void filterup(int pos) { int fa=pos/2; ss value=arr[pos]; while(pos>1) { if(!(arr[fa]<value))break; arr[pos]=arr[fa]; pos=fa; fa=pos/2; } arr[pos]=value; } void filterdown(int pos) { int ch=pos*2; ss value=arr[pos]; while(ch<=sum_element) { if(ch<sum_element&&arr[ch]<arr[ch+1])ch++; if(!(value<arr[ch]))break; arr[pos]=arr[ch]; pos=ch; ch=pos*2; } arr[pos]=value; } public: heap() { sum_element=0; } void insert(ss value) { arr[++sum_element]=value; filterup(sum_element); } void pop() { if(!sum_element)return; arr[1]=arr[sum_element--]; filterdown(1); } ss top() { return arr[1]; } bool empty() { if(sum_element)return 0; return 1; } void print() { for(int i=1;i<=sum_element;i++)printf("%lld %s\n",arr[i].x,arr[i].y); } }; heap q; int main() { /* int n,nn; scanf("%d",&n); nn=n; while(n--) { ss now; scanf("%lld %s",&now.x,now.y); q.insert(now); } q.print(); while(nn--) { printf("%lld %s\n",q.top().x,q.top().y); printf("\n"); q.pop(); } */ int n,m; ss now; scanf("%d %d",&n,&m); while(n--) { scanf("%lld %s",&now.x,now.y); q.insert(now); } while(!q.empty()&&m--) { now=q.top(); q.pop(); printf("%s\n",now.y); now.x*=2; if(now.x<(1ll<<32))q.insert(now); } return 0; }