题意: 给你很多个程序块,每个程序块只能一次执行Q个时间,若是在Q个时间内未执行完,则插入队列Q1尾部。 有unlock和lock操作,不能有两个程序同时执行lock操作,当前面的程序申请了lock操作,后面的想再申请,直接放入另一个队列Q2的尾部,当unlock操作执行时,取出Q2的首元素,加入Q1的前端。
思路:把题目看懂这个题就成功了一大半。双向队列,我用的数组模拟。
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
int wait[maxn];
queue<int>stop;
int t,n,k;
int ft,rr;
int tim[5]; //执行操作需要的时间
int var[30]; //变量值
vector<string> pro[1005]; //程序
int pronum[1005];
int getdata()
{
string temp;
int num = 0;
while(getline(cin,temp))
{
if(temp == "") continue;
pro[num].push_back(temp);
if(temp == "end") num++;
if(num == n) break;
}
return 1;
}
int Lock = -1;
int solve()
{
ft = 0, rr = -1;
for(int i = 0; i < n ; i++) //程序入队
wait[++rr] = i;
while(ft <= rr)
{
if(ft > rr) break;
int protime = k;
int x = wait[ft++]; //出队
int flag = 0; //标记lock != -1 且有lock这种情况
while(protime > 0)
{
string temp;
string v;
stringstream ss;
int j = pronum[x]++;
ss << pro[x][j];
ss >> temp;
if(temp == "lock" && Lock == -1) //未被锁
{
Lock = x;
protime -= tim[2];
}
else if(temp == "print")
{
ss >> v;
printf("%d: %d\n",x+1,var[v[0]-'a']);
protime -= tim[1];
}
else if(temp == "lock" && Lock != -1) //被锁了
{
flag = 1;
stop.push(x);
pronum[x]--;
break;
}
else if(temp == "unlock")
{
Lock = -1;
if(!stop.empty())
{
wait[--ft] = stop.front();
stop.pop();
}
protime -= tim[3];
}
else if(temp.size() == 1)
{
int value; char vr = temp[0];
string vaue = pro[x][j].substr(pro[x][j].find_last_of(' ')+1);
stringstream sa;
sa << vaue;
sa >> value;
var[vr - 'a'] = value;
protime -= tim[0];
}
else if(temp == "end")
{
protime -= tim[4];
flag = 1;
break;
}
}
if(pronum[x] == pro[x].size()) continue;
else if(flag != 1)
wait[++rr] = x;
}
return 0;
}
int main()
{
//freopen("D://in.txt","r",stdin);
scanf("%d",&t);
for(int ca = 0; ca < t; ca++)
{
scanf("%d",&n);
memset(pronum,0,sizeof(pronum));
memset(var,0,sizeof(var));
for(int i = 0; i < n ; i++)
pro[i].clear();
while(!stop.empty())
stop.pop();
for(int i = 0; i < 5; i++)
scanf("%d",&tim[i]);
scanf("%d",&k);
getdata();
if(ca != 0)
printf("\n");
solve();
}
return 0;
}