题意:给定n个程序,每种程序有五种操作,分别为 var = constant(赋值),print var (打印), lock, unlock,end。
变量用小写字母表示,初始化为0,为程序所公有(一个程序里对某个变量修改可以会影响其他程序里的这个变量),
常数小于100(也就是说最多两位数)。
每个时刻都只能有一个程序处于运行状态,其他的都在等待,上述五种操作用时分别是t1, t2, t3, t4, t5。运行中的程序,
每次最多能运行q个时间,当q个时间被用完后,它会被放在等待队列的尾部,然后再从首部取出一个程序运行,初始等待队列按输入顺序,
但是lock和unlock会改变顺序,它们总是成对出现,不会出现嵌套。如果某个程序已经执行了lock,后面还有程序执行lock,
那么这个程序就会马上被放到一个阻止队列的尾部(当然如果运行时间还没用完也就浪费了)。当unlock结束后,阻止队列中的第一个程序进入等待队列的首部。
问你程序的运行结果是什么,输出格式是第几个程序加冒号加空格加结果,两个相连的数据用空行隔开。
析:这个题主要是看懂题意,如果看懂题意,那么就比较简单了,首先是题目中多次出现队列,并且还放在首部,那么就可以知道应该是双端队列,
我们使用STL里面的,也可以自己写一个,并不难写,其他的就是模拟这个,没有什么难度,要注意的是,在结束inlock从阻止队列中拿出放在等待队列时,
要考虑是不是已经空了,否则可能使程序崩溃。
代码如下:
#include <iostream> #include <cstdio> #include <queue> #include <deque> #include <vector> #include <cstring> using namespace std; const int maxn = 1024; deque<int> wait; queue<int> block; vector<string> pram[maxn]; int t[6], Q, cnt[maxn], val[30]; bool lock; void run(int i){ int q = Q; string s; while(q > 0){ s = pram[i][cnt[i]]; if('=' == s[2]){ int num = s[4] - '0'; q -= t[1]; if(6 == s.size()) num = 10 * num + s[5] - '0'; val[s[0]-'a'] = num; } else if('i' == s[2]){ q -= t[2]; printf("%d: %d\n", i, val[s[6]-'a']); } else if('c' == s[2]){ q -= t[3]; if(lock){ block.push(i); return ; } else lock = true; } else if('l' == s[2]){ q -= t[4]; lock = false; if(!block.empty()){ wait.push_front(block.front()); block.pop(); } } else return ; ++cnt[i]; } wait.push_back(i); } int main(){ int T, n; cin >> T; while(T--){ scanf("%d", &n); for(int i = 0; i < 5; ++i) scanf("%d", &t[i+1]); scanf("%d", &Q); getchar(); string s; for(int i = 1; i <= n; ++i) pram[i].clear(); for(int i = 1; i <= n; ++i){ while(true){ getline(cin, s); pram[i].push_back(s); if(s == "end") break; } wait.push_back(i); } memset(cnt, 0, sizeof(cnt)); memset(val, 0, sizeof(val)); lock = false; while(!wait.empty()){ int p = wait.front(); wait.pop_front(); run(p); } if(T) printf("\n"); } return 0; }