题意
本题要求模拟n个程序的并行执行,每个程序按照输入的顺序编号为1~n,每个程序包含不超过25条语句,格式一共有五种,赋值,打印,lock,unlock和end。变量被所有的程序共用,用单个小写字母表示,初值为0,常数都是不超过100的整数。
每个时刻只能有一个程序在执行,其他程序处于等待状态,不同的语句执行所需要的时间不同,上述的五种语句所需时间为t1,t2,t3,t4,t5,程序的一次执行最多配给Q个单位的时间,如果时间用尽,则执行完当前语句之后,程序会被插入到一个等待队列尾部,处理器会从等待队列的队首拿出一个程序继续执行。初始等待队列就是按照输入的顺序排列的。
赋值语句将变量赋值成给定的常数,打印语句将变量的值输出。而lock和unlock语句的作用,则是申请对变量的独占访问。当程序A的lock指令被执行,就不能执行其他程序的lock指令,如果遇到其他程序的lock指令,则将这个程序停止执行,送入一个阻止队列的尾部。当A的unlock执行完毕之后,阻止队列的第一个程序进入等待队列的首部。
输入五种语句的用时和Q,以及n个程序的内容,输出print语句所在的程序编号和它们的结果。
思路
显然需要两个队列,因为变量只能是单个小写字母,所以最多有26个。要按顺序去执行等待队列里面的程序,但是如果遇到lock指令怎么办?显然我们需要一个标记来指明是否有一个程序已经执行了lock指令,如果有,再遇到lock指令时我们应该把当前程序放入阻止队列。这个标记将在unlock指令执行之后复原。
还有一个问题,一旦一个程序的unlock被执行,阻止队列的程序将插入等待队列的首部,这里违背了队列只能插入尾部的规则,所以我们要用双端队列来实现等待队列。
代码
我最终的程序是用数组模拟了一个队列。当然也可以用queue和dequeue(双端队列)去实现。
#include<cstdio>
#include<string>
#include<queue>
#include<cstring>
using namespace std;
int n=3;
int t[5];
int Q;
int values[26];
int haslocked;
char p[1005][10];
int cur[100];
int waitq[100];
int stopq[100];
int waitq_front;
int waitq_rear;
int stopq_front;
int stopq_rear;
void runprogram()
{
haslocked=0;
memset(values,0,sizeof(values));
int pro;
while(waitq_front!=waitq_rear)
{
pro=waitq[waitq_front];
waitq_front=(waitq_front+1)%100;
int timelast=Q;
int finish=0;
int c=cur[pro];
while(timelast>0)
{
char* ins=p[c];
switch (ins[2])
{
case '=':
timelast-=t[0];
values[ins[0]-'a']=ins[5]?ins[4]*10+ins[5]-'0'*11:ins[4]-'0';
break;
case 'i':
timelast-=t[1];
printf("%d: %d\n",pro+1,values[ins[6]-'a']);
break;
case 'c':
timelast-=t[2];
if(haslocked)
{
finish=1;
stopq[stopq_rear]=pro;
stopq_rear=(stopq_rear+1)%100;
}
else haslocked=1;
break;
case 'l':
timelast-=t[3];
haslocked=0;
if(stopq_rear!=stopq_front)
{
waitq_front=(waitq_front-1)%100;
waitq[waitq_front]=stopq[stopq_front];
stopq_front=(stopq_front+1)%100;
}
break;
case 'd':
finish=1;
break;
}
if(finish)break;
++c;
}
cur[pro]=c;
if(!finish)
{
waitq[waitq_rear]=pro;
waitq_rear=(waitq_rear+1)%100;
}
}
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
scanf("%d %d %d %d %d %d %d\n",&n,&t[0],&t[1],&t[2],&t[3],&t[4],&Q);
waitq_front=0;
waitq_rear=0;
stopq_front=0;
stopq_rear=0;
int j=0;
for(int i=0;i<n;++i)
{
cur[i]=j;
gets(p[j]);
while(p[j++][2]!='d')gets(p[j]);
waitq[i]=i;
}
waitq_rear=n;
runprogram();
if(N)printf("\n");
}
return 0;
}