题目:https://vjudge.net/problem/UVA-210
题意:一个CPU同时运行多个程序,但实际上每一时刻只能运行一个程序的一个指令,一个程序有若干条指令,但是CPU运行一个程序的时间最多为Qtime,每个程序有5种指令,每个指令的时间分别为t1,t2,t3,t4,t5。
Statement Type Syntax
Assignment variable = constant
Output print variable
Begin Mutual Exclusion lock
End Mutual Exclusion unlock
Stop Execution end
以上5种指令分别为,赋值,打印,锁定变量,解锁,退出程序。
在某个程序锁定变量的时候,其他程序若想锁定变量则他会被加入一个阻塞列队的尾部,当程序执行了解锁变量的时候,阻塞列队的头部会被加人到准备列队中(即将运行的程序的列队)
解法:使用两个双端列队维护准备列队个阻塞列队,ready and wait
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int T,n,t1,t2,t3,t4,t5,Qtime,Pro[100]; // Pro[i]表示程序i运行到第几条指令
int var[100];
string s;
vector<string> Inst;
deque<int> ready; // 准备列队
deque<int> wait; // 阻塞列队
bool Blok = false;
void read(){
memset(var,0,sizeof(var));
Inst.clear();
cin>>n>>t1>>t2>>t3>>t4>>t5>>Qtime;
int last_line = 0;
getline(cin,s);
fo(i,1,n){
Pro[i]=last_line; // 程序所在指令位置
while(getline(cin,s)){
Inst.push_back(s); // 存放所有指令
last_line++;
if(s=="end")break;
}
ready.push_back(i);
}
// for(int i:ready)cout<<i<<" ";
}
// 处理第i个程序
void ext(int i){
int time = Qtime; // 每次执行时间
char c;
while(time>0){
c = Inst[Pro[i]][2];
if(c == '='){// 赋值
time -= t1;
// 变量的范围在 1-99
var[Inst[Pro[i]][0]-'a'] = isdigit(Inst[Pro[i]][5]) ?(Inst[Pro[i]][4] - '0') * 10 + Inst[Pro[i]][5] - '0': Inst[Pro[i]][4] - '0';
// cout<<var[c-'a']<<endl;
}else if(c == 'i'){// 打印
time -= t2;
printf("%d: %d\n",i,var[Inst[Pro[i]][6]-'a']);
}else if(c == 'c'){ // 锁
if(Blok){ // 锁已经被锁起来了。加入阻塞列队
wait.push_back(i);
return;
}
time -= t3;
Blok = true;
}else if(c == 'l'){ // 解锁
if(!wait.empty()){ // 阻塞列队不为空的话,取阻塞列队的头部到等待列队的头部
ready.push_front(wait.front());
wait.pop_front();
}
Blok = false; // 释放锁
time -= t4;
}else{ // 退出
time -= t5;
return; // end,说明程序执行完了
}
Pro[i]++; // 本程序操作增加一次
}
// 时间问题退出的,即程序还没执行完
// cout<<i<<endl;
ready.push_back(i);
}
void solve(){
read();
while(!ready.empty()){
int x = ready.front();
ready.pop_front();
// cout<<x<<" ";
ext(x); // 依次执行准备列队的队头
}
if(T)putchar(10);
}
int main(){
scanf("%d",&T);
while(T--)solve();
// getchar();
return 0;
}