Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 1165 | Accepted: 110 | |
Case Time Limit: 5000MS |
Description
May is a lovely girl. Due to her filial piety, she wants to give a present on her mother's birthday. Because both her parents are the top programmer in the world, she decided to design a new program, a special program that is an Operating System! With the help of her excellent programming skill, May has already finished the kernel of the new OS. And the birthday is coming, she is afraid that time is not enough to finish the entire project in time. As her best net-pal, it's your duty to help her.
This is a multitask OS, processes run at the same time. There are following command in the OS:
CreateProcess(PID,Memory,Priority)
A new process is created with the process identification PID and memory size, and a priority. The priority in this command is called outer priority of a process.
AddMessage(PID,Priority)
That means, add a new message to the message queue of process PID, with the priority of Priority. The message with higher Priority will run earlier that lower ones. The Priority is called inner priority.
Run
Find out the message with biggest HP. HP is defined as the product of the inner priority of a message and the corresponding process priority. If two or more messages have the same HP, the one with smallest PID will run first. Print the information "Run: HP" to the output file, HP will be replaced by the message HP you found, or print "Empty" instead if the message queue is empty. Finally remove this message if exist.
ChangePriority(PID,NewValue)
Change the outer priority of process PID to NewValue.
GetMemory(PID,Memory)
Process PID memory increases the amount of Memory.
FreeMemory(PID,Memory)
Process PID memory decreases the amount of Memory.
RunProcess(PID)
Similar with Run command. Find out the message in the process PID message queue, print the information "Run Process: Priority" to the output file, Priority will be replaced by the message priority you found, or print "Empty" instead if the message queue is empty. Finally remove this message if exist.
CloseMaxMemory
Find out the process that used the largest number of memory and close it if exists (if tie, the one with smallest PID should be release first), or print "Empty" instead.
CloseProcess(PID)
Close the process with the identification of PID.
Whenever a process' memory is less than or equal to 0, it will be close automatically. In any of the above commands except the first one, if the PID doesn't exist, please print an "Error" to the output. For the first command, if the PID is already exist, print an "Error" and ignore this command.
This is a multitask OS, processes run at the same time. There are following command in the OS:
CreateProcess(PID,Memory,Priority)
A new process is created with the process identification PID and memory size, and a priority. The priority in this command is called outer priority of a process.
AddMessage(PID,Priority)
That means, add a new message to the message queue of process PID, with the priority of Priority. The message with higher Priority will run earlier that lower ones. The Priority is called inner priority.
Run
Find out the message with biggest HP. HP is defined as the product of the inner priority of a message and the corresponding process priority. If two or more messages have the same HP, the one with smallest PID will run first. Print the information "Run: HP" to the output file, HP will be replaced by the message HP you found, or print "Empty" instead if the message queue is empty. Finally remove this message if exist.
ChangePriority(PID,NewValue)
Change the outer priority of process PID to NewValue.
GetMemory(PID,Memory)
Process PID memory increases the amount of Memory.
FreeMemory(PID,Memory)
Process PID memory decreases the amount of Memory.
RunProcess(PID)
Similar with Run command. Find out the message in the process PID message queue, print the information "Run Process: Priority" to the output file, Priority will be replaced by the message priority you found, or print "Empty" instead if the message queue is empty. Finally remove this message if exist.
CloseMaxMemory
Find out the process that used the largest number of memory and close it if exists (if tie, the one with smallest PID should be release first), or print "Empty" instead.
CloseProcess(PID)
Close the process with the identification of PID.
Whenever a process' memory is less than or equal to 0, it will be close automatically. In any of the above commands except the first one, if the PID doesn't exist, please print an "Error" to the output. For the first command, if the PID is already exist, print an "Error" and ignore this command.
Input
First
line in the input is an integer number N (1 <= N <= 100000),
which represents the number of commands. The next N lines, each gives a
command described above. Any number given in the input file will be
non-negative integer and will not be more than 1000000000.
Output
The output format has been described above.
Sample Input
11 CloseMaxMemory CreateProcess(1,100,1) CreateProcess(2,200,1) CreateProcess(3,300,1) AddMessage(1,9) AddMessage(2,19) AddMessage(1,10) GetMemory(2,999) CloseMaxMemory Run RunProcess(1)
Sample Output
Empty Run: 10 Run Process: 9
Hint
The total size of the input files may be as large as 21.8MB.
Source
POJ Monthly,Minke
Solution
POJ上又一个通过率较低的模拟题,还有一个是POJ 1025 Department。
POJ上又一个通过率较低的模拟题,还有一个是POJ 1025 Department。
这道题比1025简单了不少,但仍有些难度。
比较难处理的操作就是Run和CloseMaxMemory,而这两个操作又比较相似。
不论简单复杂,模拟题的一般思路是分析事件(events)。这个题目对要求维护的东西叙述比较明确,所涉及的事件基本上就是所列的若干操作。
实现思路:
用map<int,pair<int,int>> info;维护process的信息
对每个process,用一个priority_queue<int> que[N]; 维护其message队列,这要求将pid离散化,用map<int,int> id;实现。
用两个set<pair<int,long long>> memory, hp; 分别支持CloseMaxMemory、Run两操作
难点:
如何实时更新上述4个数据结构。
下面具体叙述如何实现各个操作:
CreateProcess(PID,Memory,Priority)
更新info,id, memory,初始化que[id[PID]]。
AddMessage(PID,Priority)
更新que[id[pid]],hp。
Run
更新hp,对应的message队列。
ChangePriority(PID,NewValue)
更新info[PID],更新hp。
GetMemory(PID,Memory)
更新memory。
FreeMemory(PID,Memory)
更新memory,可能涉及清除一个process。
RunProcess(PID)
更新que[id[PID]],hp。
CloseMaxMemory
更新hp, memory,info;清空对应的message队列。
CloseProcess(PID)
更新hp,memory,info;清空对应的message队列。
注意:
CreatProcess(PID, Memory, Priority)操作中Memory可能为零(Any number given in the input file will be non-negative integer)。
Implementation:
1 #include <cstdio> 2 #include <set> 3 #include <map> 4 #include <queue> 5 #define LL long long 6 #define MEM second 7 #define PRO first 8 #define PID first 9 #define HP second 10 using namespace std; 11 12 const int N(1e5+5); 13 priority_queue<int> que[N]; 14 15 typedef pair<int,LL> P; 16 17 map<int,P> mp; 18 map<int,int> ID; 19 20 bool cmp(const P &a, const P &b){ 21 return a.second!=b.second?a.second>b.second:a.first<b.first; 22 } 23 24 set<P, bool(*)(const P &, const P &)> o(cmp), m(cmp); 25 26 void Erase(int pid){ 27 int id=ID[pid]; 28 if(que[id].size()){ 29 o.erase(P(pid, (LL)que[id].top()*mp[pid].PRO)); 30 que[id].pop(); 31 } 32 } 33 34 void remove_process(int pid){ 35 Erase(pid); 36 m.erase(P(pid, mp[pid].MEM)); 37 int id=ID[pid]; 38 for(; que[id].size(); que[id].pop()); 39 mp.erase(pid); 40 } 41 42 void Insert(int pid){ 43 int id=ID[pid]; 44 if(que[id].size()){ 45 o.insert(P(pid, (LL)que[id].top()*mp[pid].PRO)); 46 } 47 } 48 49 void close_process(int pid){ 50 if(mp.find(pid)==mp.end()) puts("Error"); 51 else remove_process(pid); 52 } 53 54 void close_max_memory(){ 55 if(m.empty()) puts("Empty"); 56 else remove_process(m.begin()->PID); //error-prone 57 } 58 59 void run_process(int pid){ 60 if(mp.find(pid)==mp.end()){ 61 puts("Error"); 62 return; 63 } 64 int id=ID[pid]; 65 if(que[id].empty()) puts("Empty"); 66 else{ 67 printf("Run Process: %d ", que[id].top()); 68 Erase(pid), Insert(pid); 69 } 70 } 71 72 void modify_memory(int pid, int mem){ 73 if(mp.find(pid)==mp.end()){ 74 puts("Error"); 75 return; 76 } 77 if(mp[pid].MEM+mem<=0) 78 remove_process(pid); 79 else{ 80 P now=mp[pid]; 81 m.erase(P(pid, now.MEM)); 82 m.insert(P(pid, now.MEM+mem)); 83 mp[pid].MEM+=mem; 84 } 85 } 86 87 void change_priority(int pid, int pro){ 88 if(mp.find(pid)==mp.end()){ 89 puts("Error"); 90 return; 91 } 92 int id=ID[pid]; 93 if(que[id].size()){ 94 int i_pro=que[id].top(); 95 o.erase(P(pid, (LL)mp[pid].PRO*i_pro)); 96 o.insert(P(pid, (LL)pro*i_pro)); 97 } 98 mp[pid].PRO=pro; 99 } 100 101 void run(){ 102 if(o.empty()) puts("Empty"); 103 else{ 104 printf("Run: %lld ", o.begin()->HP); 105 int pid=o.begin()->PID; 106 Erase(pid), Insert(pid); 107 } 108 } 109 110 void add_message(int pid, int pro){ 111 if(mp.find(pid)==mp.end()){ 112 puts("Error"); 113 return; 114 } 115 int id=ID[pid]; 116 if(que[id].size()){ 117 int i_pro=que[id].top(); 118 o.erase(P(pid, (LL)i_pro*mp[pid].PRO)); 119 } 120 que[id].push(pro); 121 o.insert(P(pid, (LL)que[id].top()*mp[pid].PRO)); 122 } 123 124 int tail; 125 126 void create_process(int pid, int mem, int pro){ 127 if(mp.find(pid)!=mp.end()){ 128 puts("Error"); 129 return; 130 } 131 if(mem){ 132 mp[pid]=P(pro, mem); 133 m.insert(P(pid, mem)); 134 ID[pid]=tail++; 135 } 136 } 137 138 char s[100]; 139 140 int main(){ 141 int n, pid, mem, pro; 142 for(scanf("%d", &n); n--; ){ 143 scanf("%s", s); 144 if(s[0]=='C'){ 145 if(s[1]=='r'){ 146 sscanf(s, "CreateProcess(%d,%d,%d)", &pid, &mem, &pro); 147 create_process(pid, mem, pro); 148 } 149 else if(s[1]=='l'){ 150 if(s[5]=='M') 151 close_max_memory(); 152 else{ 153 sscanf(s, "CloseProcess(%d)", &pid); 154 close_process(pid); 155 } 156 } 157 else{ 158 sscanf(s, "ChangePriority(%d,%d)", &pid, &pro); 159 change_priority(pid, pro); 160 } 161 } 162 else if(s[0]=='A'){ 163 sscanf(s, "AddMessage(%d,%d)", &pid, &pro); 164 add_message(pid, pro); 165 } 166 else if(s[0]=='G'){ 167 sscanf(s, "GetMemory(%d,%d)", &pid, &mem); 168 modify_memory(pid, mem); 169 } 170 else if(s[0]=='F'){ 171 sscanf(s, "FreeMemory(%d,%d)", &pid, &mem); 172 modify_memory(pid, -mem); 173 } 174 else{ 175 if(s[3]){ 176 sscanf(s, "RunProcess(%d)", &pid); 177 run_process(pid); 178 } 179 else run(); 180 } 181 } 182 return 0; 183 }