本题需要你模拟一些简单程序,每一个程序有以下5种指令:
- var = val 给变量赋值,简单起见保证变量名为一个字母,变量为所有进程共用,并且初始为0,保证val是不大于100的正整数;
- print var 输出变量var;
- lock 对所有变量申请独占访问 (不影响赋值和打印)
- unlock 解除独占访问
- end 结束程序
以上指令分别耗时t1,t2,t3,t4,t5的时间,一开始进程按照输入顺序依次插入到等待队列中,每次从等待队列队首选择一个进程执行。每个进程有一个配额(限定时间)Q,当配额用完时,该进程会在执行完当前语句后立即被插入到一个等待队列尾部中。
但是lock语句和unlock语句会改变进程的执行顺序。当一个程序执行了lock语句,其他进程再执行到lock语句时会被立即插入到一个阻止队列队尾,当程序执行到unlock语句时,阻止队列的队首的第一个进程会被立即插入到等待队列队首。
程序按输入顺序编号为(1-5)
要点:
1.Any instruction currently being
executed when the time quantum expires will be allowed to complete.
语句一旦执行了,就一定可以完成,
即不存在时间只剩下1s 但是执行一个需要2s的语句 执行一半的情况,一定会将这需要2s的语句执行完毕
2.阻止队列会插入到等待队列的队首
提示使用双端队列 deque
3.等待队列为空,阻止队列也一定为空,因为lock配套unlock,lock进去的也配套unlock,最后阻止队列一定会为空
代码:
#include<iostream>
#include<queue>
#include<string>
#include<sstream>
#include<cstring>
using namespace std;
int Lockid = 0; //0表示没lock 正整数表示成功执行lock的程序
int var[26];
struct Program {
int id;
int line; //行数
int nowLine; //当前行数
string s[30]; //程序
};
deque<Program> waitQ; //等待队列
queue<Program> blockQ; //阻止队列
int main() {
ios::sync_with_stdio(false);
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T;
cin >> T;
int kase = 0;
while (T--) {
if (kase++) {
cout << endl;
}
// 数量 赋值语句 打印 LOCK UNLOCK END 时间
memset(var, 0, sizeof(var));
int t[6];
int n, Q;
cin >> n;
for (int i = 1; i <= 5; i++) cin >> t[i];
cin >> Q;
//完成输入
for (int i = 1; i <= n; i++) {
Program p;
string statement;
int line = 0;
p.id = i;
p.nowLine = 0;
while (cin >> statement) {
string command;
//赋值语句
if (statement.length() == 1) {
char ignoreCh;
cin >> ignoreCh;
int constValue;
cin >> constValue;
char buf[10];
sprintf(buf, "1 %c %d", statement[0], constValue);
command = buf;
}
else if (statement == "print") {
char var;
cin >> var;
char buf[10];
sprintf(buf, "2 %c", var);
command = buf;
}
else if (statement == "lock") {
command = "3";
}
else if (statement == "unlock") {
command = "4";
}
else if (statement == "end") {
command = "5";
}
//cout << command << endl;
line++;
p.s[line] = command;
if (command == "5")
break;
}
p.line = line;
waitQ.push_back(p);
}
//处理
while (!waitQ.empty()) {
int time = Q;
Program p;
p = waitQ.front();
waitQ.pop_front();
bool flag = true;
while (time > 0) {
p.nowLine++;
string s = p.s[p.nowLine];
if (s[0] == '5') {
break;
}
if (s[0] == '4') {
Lockid = 0;
if (!blockQ.empty()) {
waitQ.push_front(blockQ.front());
blockQ.pop();
}
time -= t[4];
}
if (s[0] == '3') {
if (Lockid == 0)
{
Lockid = p.id;
time -= t[3];
}
else {
p.nowLine--; //没执行成功
blockQ.push(p);
flag = false;
break;
}
}
if (s[0] == '2') {
time -= t[2];
cout << p.id << ": " << var[s[2] - 'a'] << endl;
}
if (s[0] == '1') {
time -= t[1];
stringstream ss(s);
int ignoreInt, needInt;
char ch;
ss >> ignoreInt >> ch >> needInt;
var[ch - 'a'] = needInt;
}
}
if (p.nowLine != p.line && flag) {
waitQ.push_back(p);
}
}
}
}
总结:
1.输入可能处理的有点麻烦
2.双端队列的使用