UVa 210 Concurrency Simulator(双端队列)

来源:互联网 发布:剑三正太捏脸数据南风 编辑:程序博客网 时间:2024/06/07 10:18

题意:

你的任务是模拟n个程序(按输入顺序编号为1~n)的并行执行。每个程序包含不超过25条语句,格式一共有5种:var = constant (赋值):print var (打印):lock:unlock:end。

变量用单个小写字母表示,初始为0,为所有程序公有(因此在一个程序里对某个变量赋值可能会影响另一个程序) 。常数是小于100的非负整数。

每个时刻只能有一个程序处于运行状态,其他程序均处于等待状态。上述5种语句分别需要t1、t2、t3、t4、t5单位时间。运行态的程序每次最多运行Q个单位时间(称为配额)。当一个程序的配额用完之后,把当前语句(如果存在)执行完之后该程序会被插入一个等待队列中,然后处理器从队首取出一个程序继续执行。初始等待队列包含按输入顺序排列的各个程序,但由于lock\unlock语句的出现,这个顺序可能会改变。

lock的作用是申请对所有变量的独占访问。lock和unlock总是成对出现,并且不会嵌套。lock总是在unlock的前面。当一个程序成功执行完lock指令之后,其他程序一但试图执行lock指令,就会马上被放到一个所谓的阻止队列的尾部 (没有用完的配额就浪费了),当unlock执行完毕后,阻止队列的第一个程序进入等待队列的首部。


Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

The first line of the input file consists of seven integers separated by spaces. These integers specify (in order): the number of programs which follow, the unit execution times for each of the five statements (in the order given above), and the number of time units comprising the time quantum. The remainder of the input consists of the programs, which are correctly formed from statements according to the rules described above.

All program statements begin in the first column of a line. Blanks appearing in a statement should be ignored. Associated with each program is an identification number based upon its location in the input data (the first program has ID = 1, the second has ID = 2, etc.).

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

Your output will contain of the output generated by the print statements as they occur during the simulation. When a print statement is executed, your program should display the program ID, a colon, a space, and the value of the selected variable. Output from separate print statements should appear on separate lines.

A sample input and correct output are shown below.

Sample Input

13 1 1 1 1 1 1a = 4print alockb = 9print bunlockprint benda = 3print alockb = 8print b unlockprint bendb = 5a = 17print aprint blockb = 21print bunlockprint bend

Sample Output

1: 32: 33: 173: 91: 91: 92: 82: 83: 21

3: 21


解题思路:
STL队列,双端队列的应用  ;
用双端队列维护即将执行的程序 ,再用个队列维护等待变量释放的程序,用lock表示变量锁定状态;
先将所有程序依次放到执行队列中,每次取出队首程序运行不超过lim时间,未运行完又放到执行队列队尾;   
遇到lock时,若当前锁定状态为false就将锁定状态变为true,否则将当前程序放到等待队列队尾并结束运行;  
遇到unlock时,若等待队列有程序,就将等待队列队首程序放到执行队列队首;
遇到end时,退出当前执行(不再进队尾)。

非常好的一道模拟题,看着别人的解题报告好不容易给磕出来了,值得反复做。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int maxn = 1005;deque<int> qr;//等待队列queue<int> qb;//阻止队列vector<string> prg[maxn];int n,t[5],p[maxn],var[26],Q;//p[i]存放第i个程序执行的语句序号,var[i]存放的是变量i的值bool lock;void run(int i){int rt = Q,v;string cur;while(rt > 0){cur = prg[i][p[i]];if(cur[2] == '=')//选择第三个字符是因为所有语句第三个字符都不一样{rt -= t[0];v = cur[4] - '0';if(cur.size() == 6)v = v*10 + cur[5] - '0';var[cur[0]-'a'] = v;}else if(cur[2] == 'i'){rt -= t[1];printf("%d: %d\n",i,var[cur[6]-'a']);}else if(cur[2] == 'c'){rt -= t[2];if(lock){qb.push(i);return;}elselock = true;}else if(cur[2] == 'l'){rt -= t[3];lock = false;if(!qb.empty()){int m = qb.front();qb.pop();qr.push_front(m);}}elsereturn;p[i]++;}qr.push_back(i);//程序配额用完后插入等待队列队尾}int main(int argc, char const *argv[]){int N;scanf("%d",&N);string s;while(N--){scanf("%d",&n);for(int i= 0;i < 5;i++)scanf("%d",&t[i]);scanf("%d",&Q);for(int i = 1;i <= n;i++){prg[i].clear();while(getline(cin,s)){if(s == "")//如果s为空串,即为回车换行符continue;prg[i].push_back(s);if(s == "end")break;}qr.push_back(i);}memset(p,0,sizeof(p));memset(var,0,sizeof(var));while(!qr.empty()){int cur = qr.front();qr.pop_front();run(cur);}if(N)printf("\n");}return 0;}


0 0
原创粉丝点击