UVA

来源:互联网 发布:部落冲突闪电数据 编辑:程序博客网 时间:2024/05/29 09:40
/*  本题借鉴了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': //printcout << pid + 1 << ": " << var[p[6] - 'a'] << endl;q -= c[1];break;case 'c': //lockif (locked) {block.push(pid); return;}locked = true;q -= c[2];break;case 'l': //unlocklocked = false;if (!block.empty()){int pid2 = block.front();block.pop();ready.push_front(pid2);}q -= c[3];break;case 'd': //endreturn;}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 debugusing 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': //printcout << pid + 1 << ": " << var[p[6] - 'a'] << endl;q -= c[1];break;case 'c': //lockif (locked) {block.push(pid); return;}locked = true;q -= c[2];break;case 'l': //unlocklocked = false;if (!block.empty()){int pid2 = block.front();block.pop();ready.push_front(pid2);}q -= c[3];break;case 'd': //endreturn;}ip[pid]++;}ready.push_back(pid); //如果程序没有读完,重新进入等待队列,作为队尾 }int main(){#ifdef debugfreopen("E:\\in.txt", "r", stdin);freopen("E:\\out.txt", "w", stdout);#endifcin.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 debugfclose(stdin);fclose(stdout);#endifreturn 0;}


原创粉丝点击