POJ #2448 A New Operating System

Posted Pat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ #2448 A New Operating System相关的知识,希望对你有一定的参考价值。

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.

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


Solution
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)
更新infoidmemory,初始化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)
更新hpmemory,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\n", 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\n", 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 }

 

 
 

以上是关于POJ #2448 A New Operating System的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 2448 无尽的生命

POJ 1740:A New Stone Game

POJ 1740 A New Stone Game(博弈)

poj1740 A New Stone Game

poj1740 A New Stone Game

博弈论(男人八题):POJ 1740 A New Stone Game