题意:
模拟n个程序运行
格式一共有5种:var = constant(赋值);print var(打印);lock;unlock;end,
上述5种语句分别需
要t1、t2、t3、t4、t5单位时间
运行态的程序每次最多运行Q个单位时间(称为配额)
一个程序的配额用完之后,把当前语句(如果存在)执行完之后该程序会被插入一个等待队
列中,然后处理器从队首取出一个程序继续执行。
lock的作用是申请对所有变量的独占访问。lock和unlock总是成对出现,并且不会嵌套。
lock总是在unlock的前面。当一个程序成功执行完lock指令之后,其他程序一旦试图执行lock
指令,就会马上被放到一个所谓的阻止队列的尾部(没有用完的配额就浪费了)。当unlock
执行完毕后,阻止队列的第一个程序进入等待队列的首部。
输出运行程序的print
分析:
这道题题目很长,理解会有点困难, 没看过原题做的话会有挺多坑。
1.executed when the time quantum expires will be allowed to complete.
就是如果执行完当前指令后Q<0, 那么这个程序仍然可以运行, 之后就会结束运行
2.独占访问我一开始理解为如果被一个程序lock了, 那么只有这个lock程序可以修改变量, 其实并不是, lock后其他程序仍然可以修改变量。
3.那么这题就可以看成2个队列的模拟题了, 一个等待队列deque, 一个阻止队列queue。
4.一开始将所有数据先输入一个数组中, 然后用一个数组记录每个程序的初始行号, 这样模拟会比较方面。
5.找出不同指令的不同点, 用switch一次判断出来。
#include <bits/stdc++.h> using namespace std; const int maxl = 10000; char pg[maxl][10]; int n, quan, locked,t[5], pgline[maxl]; int val[26]; deque<int> Wait; queue<int> Block; void run(int num) { int q = quan; while(q > 0){ char *str = pg[pgline[num]]; switch(str[2]){ case '='://var val[str[0] - 'a'] = isdigit(str[5]) ?(str[4] - '0') * 10 + str[5] - '0': str[4] - '0'; q -= t[0]; break; case 'i':// print printf("%d: %d ", num + 1, val[str[6]-'a']); q -= t[1]; break; case 'c': // lock if(locked){ Block.push(num); return; } locked = 1; q -= t[2]; break; case 'l': // unlock locked = 0; if(!Block.empty()){ Wait.push_front(Block.front()); Block.pop(); } q -= t[3]; break; case 'd': // end return; } pgline[num] ++; } Wait.push_back(num); } int main() { int T; scanf("%d", &T); while(T--){ int line = 0; memset(pgline,0,sizeof(pgline)); memset(pg,0,sizeof(pg)); memset(val,0,sizeof(val)); scanf("%d %d %d %d %d %d %d ", &n, &t[0], &t[1], &t[2], &t[3], &t[4], &quan); for(int i = 0; i < n; i++){ gets(pg[line++]); pgline[i] = line - 1; while(pg[line-1][2] != 'd') gets(pg[line++]); Wait.push_back(i); } locked = 0; while(!Wait.empty()){ int pick = Wait.front(); Wait.pop_front(); run(pick); } if(T) printf(" "); } return 0; }