6-1 并行程序模拟

原题链接:https://vjudge.net/problem/UVA-210

题意:给定n个程序,每种程序有五种操作,分别为 var = constant(赋值),print var (打印), lock, unlock,end

变量用小写字母表示,初始化为0,为程序所公有(一个程序里对某个变量修改可以会影响其他程序里的这个变量),

常数小于100(也就是说最多两位数)。

每个时刻都只能有一个程序处于运行状态,其他的都在等待,上述五种操作用时分别是t1, t2, t3, t4, t5。运行中的程序,

每次最多能运行q个时间,当q个时间被用完后,它会被放在等待队列的尾部,然后再从首部取出一个程序运行,初始等待队列按输入顺序,

但是lock和unlock会改变顺序,它们总是成对出现,不会出现嵌套。如果某个程序已经执行了lock,后面还有程序执行lock,

那么这个程序就会马上被放到一个阻止队列的尾部(当然如果运行时间还没用完也就浪费了)。当unlock结束后,阻止队列中的第一个程序进入等待队列的首部。

问你程序的运行结果是什么,输出格式是第几个程序加冒号加空格加结果,两个相连的数据用空行隔开。

思路:

    整体来看,正常运行时,依次对每个程序,在配额q时间内运行语句,完了就下一个程序,这里要分辨出不同程序和对应的时间。当遇到lock时,要挂起程序,在另一个地方等待,已有其他程序在等待,就排在其后面,所以需要准备另一块空间。然后有unlock可以回来,按照“先进先出”的特性,这里可以用双端队列来运行,另一个队列来放等待的程序(这里不是很复杂,也可以用其他数据结构代替,但显然队列最方便)

代码:

#include<cstdio>

#include<queue>

#include<cstring>

#include<cstdlib>

#include<cctype>

usingnamespacestd;

constintmaxn =1000;

deque readyQ;

queue blockQ;

intn, quantum, c[5], var[26], ip[maxn];//ip[pid]是程序pid的当前行号。所有程序都存在prog数组,更类似真实的情况,代码也更短

boollocked;

charprog[maxn][10];

voidrun(intpid) {

intq = quantum;

while(q >0) {

char*p = prog[ip[pid]];

switch(p[2]) {

case'=':

var[p[0] -'a'] =isdigit(p[5]) ? (p[4] -'0') *10+ p[5] -'0': p[4] -'0';

q -= c[0];

break;

case'i'://print

printf("%d: %d\n", pid+1, var[p[6] -'a']);

q -= c[1];

break;

case'c'://lock

if(locked) { blockQ.push(pid);return; }

locked =true;

q -= c[2];

break;

case'l'://unlock

locked =false;

if(!blockQ.empty()) {

intpid2 = blockQ.front(); blockQ.pop();

readyQ.push_front(pid2);

        }

q -= c[3];

break;

case'd'://end

return;

    }

    ip[pid]++;

  }

readyQ.push_back(pid);

}

intmain() {

intT;

scanf("%d", &T);

while(T--) {

scanf("%d %d %d %d %d %d %d\n", &n, &c[0], &c[1], &c[2], &c[3], &c[4], &quantum);

memset(var,0,sizeof(var));

intline =0;

for(inti =0; i < n; i++) {

fgets(prog[line++], maxn, stdin);

ip[i] = line -1;

while(prog[line -1][2] !='d')

fgets(prog[line++], maxn, stdin);

readyQ.push_back(i);

    }

locked =false;

while(!readyQ.empty()) {

intpid = readyQ.front(); readyQ.pop_front();

run(pid);

    }

if(T)printf("\n");

  }

return0;

}