/* 本题借鉴了LRJ在github上放的入门经典的代码库 收获 && 总结: 1. 双端队列deque 下面这个博客总结的比较细致 2. fgets函数 http://www.cnblogs.com/aexin/p/3908003.html 3. 该题最好不要用C++的getline,也不要用string,最好还是用字符串数组 char[][],因为我一开始用它们两时,尽管和LRJ的思路基本一样,还是被判Runtime Error,改了以后又是各种WA,后来改了许久才改对...对于输入格式的处理,还是用fgets比较好(虽然我暂时没有足够的理论依据支持这点) */
//一开始我是用C++写的,但是bug一直找不出来,只能先换C来写一次 #include <iostream> #include <queue> #include <cstring> #include <cctype> #include <cstdlib> #include <cstdio> #define rep(i, n) for (int i = 0; i < (n); i++) using namespace std; const int maxn = 1e3; deque<int> ready; queue<int> block; int n, quantum, c[5], var[26], ip[maxn]; bool locked; char code[maxn][20]; //ip[pid] 保存pid程序当前需执行的第一条代码,在code中的下标。最初是记录没个程序第一行代码的位置,带程序开始运行语句以后,没运行一句代码,对应程序的pid++ //所有程序存在code数组 void run(int pid) { int q = quantum; while (q > 0) { char*p = code[ip[pid]]; switch (p[2]) { case '='://赋值,因为常量给定小于100,只要判断其是否为两位,一位和两位的情况,分开处理即可,用 isdigit函数可简化代码 var[p[0] - 'a'] = isdigit(p[5]) ? (p[4] - '0') * 10 + p[5] - '0' : p[4] - '0'; q -= c[0]; break; case 'i': //print cout << pid + 1 << ": " << var[p[6] - 'a'] << endl; q -= c[1]; break; case 'c': //lock if (locked) { block.push(pid); return; } locked = true; q -= c[2]; break; case 'l': //unlock locked = false; if (!block.empty()) { int pid2 = block.front(); block.pop(); ready.push_front(pid2); } q -= c[3]; break; case 'd': //end return; } ip[pid]++; } ready.push_back(pid); //如果程序没有读完,重新进入等待队列,作为队尾 } int main() { int t; cin >> t; while(t--) { cin >> n; rep(i, 5) cin >> c[i]; cin >> quantum; getchar(); memset(var, 0, sizeof(var)); int line = 0; rep(i, n) //先将n个程序的所有代码读入,保存到code { fgets(code[line++], maxn, stdin); ip[i] = line - 1; while (code[line - 1][2] != 'd')//不断读取代码,直到读完每组的end fgets(code[line++], maxn, stdin); ready.push_back(i); //将这个程序压入等待队列 } locked = false; while (!ready.empty()) { int tp = ready.front(); ready.pop_front(); run(tp); } if (t) cout << endl; } return 0; }
//后来实在不甘心自己写的C++版本,一直有个bug找不出来,于是用udebug上的两组数据不断比对,调试、加输出,把可能有错的地方轮流换着修改,最后终于用C++写出了AC代码 //fgets换为getline以后,就一直出错!!!(hhh,这句好像是我昨天一直RE或者WA时,十分怨念,写下的注释) #include <iostream> #include <queue> #include <string> #include <cstring> #include <cctype> #include <cstdlib> #include <fstream> #define rep(i, n) for (int i = 0; i < (n); i++) //#define debug using namespace std; const int maxn = 1e3; deque<int> ready; queue<int> block; int n, quantum, c[5], var[26], ip[maxn]; bool locked; string code[maxn]; //ip[pid] 保存pid程序当前需执行的第一条代码,在code中的下标。最初是记录没个程序第一行代码的位置,带程序开始运行语句以后,没运行一句代码,对应程序的pid++ //所有程序存在code数组 void run(int pid) { int q = quantum; while (q > 0) { string p = code[ip[pid]]; switch (p[2]) { case '=': //赋值,因为常量给定小于100,只要判断其是否为两位,一位和两位的情况,分开处理即可,用 isdigit函数可简化代码 var[p[0] - 'a'] = isdigit(p[5]) ? (p[4] - '0') * 10 + p[5] - '0' : p[4] - '0'; q -= c[0]; break; case 'i': //print cout << pid + 1 << ": " << var[p[6] - 'a'] << endl; q -= c[1]; break; case 'c': //lock if (locked) { block.push(pid); return; } locked = true; q -= c[2]; break; case 'l': //unlock locked = false; if (!block.empty()) { int pid2 = block.front(); block.pop(); ready.push_front(pid2); } q -= c[3]; break; case 'd': //end return; } ip[pid]++; } ready.push_back(pid); //如果程序没有读完,重新进入等待队列,作为队尾 } int main() { #ifdef debug freopen("E:\in.txt", "r", stdin); freopen("E:\out.txt", "w", stdout); #endif cin.tie(0); cin.sync_with_stdio(false); int t; cin >> t; string temp; while (t--) { // getline(cin, temp); cin >> n; rep(i, 5) cin >> c[i]; cin >> quantum; getline(cin, temp); // getchar(); memset(var, 0, sizeof(var)); int line = 0; rep(i, n) //先将n个程序的所有代码读入,保存到code { getline(cin, code[line++]); // cout << "test: " << code[line - 1] << endl;; ip[i] = line - 1; while (code[line - 1] != "end") //不断读取代码,直到读完每组的end { getline(cin, code[line++]); // cout << "test: " << code[line - 1] << endl; } ready.push_back(i); //将这个程序压入等待队列 } locked = false; while (!ready.empty()) { int tp = ready.front(); ready.pop_front(); run(tp); } if (t) cout << endl; } #ifdef debug fclose(stdin); fclose(stdout); #endif return 0; }