uva210_ConcurrencySimulator
说来惭愧,已经临近开学,昨天晚上才鼓起勇气决定开始刷题。
不抒情,直奔重点。
类型:结合队列、双端队列这类数据结构的模拟题。难度不大,但细节居多。
题意:
大体:输入为n个程序,每个程序若干种语句,每种语句时间给定。调度按照时间片方式。输出为[输出语句]中的输出内容。
额外:加入了锁机制。lock的作用是申请对所有变量的独占访问,unlock解锁。当有程序执行lock之后,其他程序试图执行lock,将进入所谓阻止队列中。遇到unlock才有机会再次进入等待队列。
分析:
题意其实涉及到了两种队列:等待队列和阻止队列。
注意到阻止队列中的程序会插到等待队列中,等待队列应当为双端队列,可用数组手动模拟,或者利用STL中的deque。
注意点:
1.I/O格式常规。原题所给样例中并非完整输入,而只是一个case,省略了case个数的输入。
2.“其他程序在当前已经有程序lock的时候试图执行lock,将进入阻止队列”,仅仅是试图,并未执行。
感悟:
1.充分理解题意。绝大多数bug都是逻辑上的错误,而逻辑上的错误通常是因为题意理解有误,一旦如此,后面发现bug的时候将会陷入思维僵局,很难自拔。
因此,首先需要从源头上做到充分理解题意。而在遇到不幸仍发生之时,也要及时让头脑保持冷静,重新理解题意,不可陷入无谓的僵局。
2.代码即逻辑。代码的流畅即逻辑的清晰。哪里是循环?哪里是条件分支?它们的条件分别是什么?务必保证明确。
3.养成良好的编码习惯。比如变量命名的规范;只要是for if else一律用{},即代码块,不必为了代码量少而牺牲这个{},因为很有可能后面注意到考虑不周而发现语句不止一条需要放在代码块里,再来加{},会在一定程度上影响思路。
4.务必用更好的编程思路:先打整体框架,再局部依次完善。否则很容易瞻前不顾尾,即陷入了某个局部的逻辑里,当再来完成整体上的逻辑时,容易考虑不严谨,忽略很多东西。
这实际上就是要用广度优先,而非深度优先的策略。
#include <iostream> #include<string> #include<vector> #include<queue> #include<cstring> #include<cstdio> using namespace std; const int maxn = 10000; int n, t1, t2, t3, t4, t5, Q; int vals[26]; vector<queue<string> >pros; int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int T; cin >> T; while(T--){ pros.clear(); memset(vals, 0, sizeof(vals)); cin >> n >> t1 >> t2 >> t3 >> t4 >> t5 >> Q; getchar(); for(int i = 0; i < n; i++){ pros.push_back(queue<string>()); string cmd; while(getline(cin, cmd) && cmd != "end"){ pros[i].push(cmd); } pros[i].push(cmd); //cmd = end } int q[maxn]; int head = 0, tail = 0; for(int i = 0; i < n; i++){ q[tail++] = i; } queue<int>stop; bool lock = false; while(head != tail){ bool cur_lock = false; int idx = q[head++]; int time = 0; while(!pros[idx].empty() && time < Q){ string cmd = pros[idx].front(); if(cmd.find("print") != -1){ cout << idx + 1 << ": " << vals[cmd[6] - 'a'] << endl; time += t2; } else if(cmd.find("unlock") != -1){ if(!stop.empty()){ q[--head] = stop.front(); stop.pop(); } // }else{ // lock = false; // } lock = false;//只要unlock了就意味着解除了lock。一开始误以为阻止队列里的程序都已经执行了Lock,不然。 time += t4; } else if(cmd.find("lock") != -1){ if(lock){ //如果已经有程序上了锁,则当前程序进阻止队列 stop.push(idx); cur_lock = true; break; } lock = true; time += t3; } else if(cmd.find("end") != -1){ time += t5; } else { //variable = constant int len = cmd.size() - 1; int val = cmd[len] - 48; if(cmd[len-1] >= 48 && cmd[len-1] <= 57){ val += (cmd[len-1] - 48)*10; } vals[cmd[0] - 97] = val; time += t1; } pros[idx].pop(); } if(!pros[idx].empty() && !cur_lock){ //该程序尚未执行完 并且 未进阻止队列 q[tail++] = idx; } } if(T != 0) cout << endl; } return 0; }