题目链接:https://vjudge.net/problem/UVA-210
这一题给我的感觉是,难度并不是很大,但难点在于理解题目,读懂题目之后将题目里描述的规则用代码写出来就行了。
核心有两点:一是维护ready queue和block queue;二是根据题目对模拟规则的描述进行各个statement执行的实现。
在ac之后,我看了一个lrj书中提供的代码,整体方法是一致的,但是他的代码非常短,只有77行,而我的代码达到了100多行,这说明我的钥匙思维还不够凝练。仔细分析一下代码的差异,主要在输入数据的存储上和对时间片部分的维护上,我的重复代码相当的多。lrj的解法提供了解决这种有时间限制问题的一种解法,以后还可以借鉴。
附上我的代码。
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<sstream>
using namespace std;
const int max_statements=25;
const int max_programs = 50;
int program_num = 0;
map<char, int> quantum;
class Program {
public:
vector<string> statements;
int id;
int execute_line;
};
Program read_Q[max_programs];
int Qfront = 0;
int Qend = 0;
int sizeQ = 0;
void push_front(Program P) {
Qfront = (Qfront - 1 + max_programs) % max_programs;
read_Q[Qfront] = P;
sizeQ++;
}
void push_end(Program P) {
read_Q[Qend] = P;
Qend = (Qend + 1) % max_programs;
sizeQ++;
}
Program pop() {
Program p = read_Q[Qfront];
Qfront = (Qfront + 1) % max_programs;
sizeQ--;
return p;
}
queue<Program> block_Q;
void clear() {
Qfront = 0;
Qend = 0;
quantum.clear();
}
int main() {
//freopen("input.txt","r",stdin);
//freopen("output.txt", "w", stdout);
int case_num = 0;
cin >> case_num;
int pt = case_num;
while (case_num--)
{
getchar();
clear();
int table[26] = {0};
cin >> program_num;
int qt = 0;
int quantumT = 0;
cin >> qt;
quantum['='] = qt;
cin >> qt;
quantum['i'] = qt;
cin >> qt;
quantum['c'] = qt;
cin >> qt;
quantum['l'] = qt;
cin >> qt;
quantum['d'] = qt;
cin >> quantumT;
for (int i = 0; i < program_num; i++)
{
Program program;
program.id = i+1;
program.execute_line = 0;
string s;
while (getline(cin, s)) {
if (s == "")continue;
if (s != "end") {
program.statements.push_back(s);
}
else {
program.statements.push_back(s);
break;
}
}
push_end(program);
}
if (case_num < (pt - 1))cout << endl;
//simulate the program execute
int lock = 0;
while (sizeQ > 0) {
Program p = pop();
int time = 0;
for (int i = p.execute_line; i < p.statements.size(); i++)
{
//judge the current statement is lock or unlock
if (p.statements[i] == "lock") {
//if current statement is lock , it need to judge whether the state is lock.
if (lock == 0) {
lock = p.id;
time += quantum[p.statements[i][2]];
p.execute_line++;
if (time >= quantumT) {
push_end(p);
break;
}
}
else {
block_Q.push(p);//the quantum remained is given up.
p.execute_line++;
break;
}
}
else if (p.statements[i] == "unlock") {
lock = 0;
if (block_Q.size() > 0) {
push_front(block_Q.front());
block_Q.pop();
}
time += quantum[p.statements[i][2]];
p.execute_line++;
if (time >= quantumT) {
push_end(p);
break;
}
}
else if (p.statements[i][2] == '=') {
stringstream stream(p.statements[i].substr(4));
int num;
stream >> num;
table[p.statements[i][0] - 'a'] = num;
time += quantum[p.statements[i][2]];
p.execute_line++;
if (time >= quantumT) {
push_end(p);
break;
}
}
else if (p.statements[i][2] == 'i') {
cout << p.id << ": " << table[p.statements[i][6] - 'a'] << endl;;
time += quantum[p.statements[i][2]];
p.execute_line++;
if (time >= quantumT) {
push_end(p);
break;
}
}
else if(p.statements[i][2] == 'd') {
break;
}
}
}
}
return 0;
}