考察:模拟,双端队列
这道题卡了我不少时间,题目里面有两个队列,一个等待队列一个阻塞队列,什么时候会有程序进入阻塞队列呢,就是已经有程序执行lock指令,并且还没有unlock指令解锁的时候,有一个程序试图执行lock指令,那么它被移到阻塞队列的队尾,这里我们可以设置一个变量,来简单的表示当前是不是上锁的状态,
我错的地方是unlock指令,这个指令的时候要从阻塞队列队头拿出一个程序放到等待队列队头,但是我没有对阻塞队列判空,因为我看题目说的两种指令成对出现没有嵌套,想着只要unlock,那么阻塞队列里面一定有程序,没有判空,这就错了,因为很简单的,一开始如果执行了lock指令,没有程序执行lock指令,那么下次执行unlock指令的时候,阻塞队列就是空的,所以每次unlock的时候,试图从阻塞队列里面取程序的时候要先判空,这也是队列和栈两种数据结构的基本功把,栈满也要考虑,但是那都是逻辑上的问题,逻辑满了实际还是能放进去的,就会答案错误,空如果不判断的话就是程序运行时错误,连答案错误都没有
最后这道题要注意的地方真的不少,
首先pdf上面的样例格式是错误的,少了一个总的样例数,
输出的时候两组数据之间要有一个空行,
变量只可能是一个小写字母,所有程序共享,初值为0,所以可以在准备处理之前就映射好值,
当前程序运行语句的时间大于剩余可用时间,只要剩余可用时间不为0,那么这条语句要执行完,
lock的时候如果当前已经处于上锁的状态,那么这个lock语句不被执行,这个程序直接被放到阻塞队列,
我们每次从等待队列的队首取出一个程序,是当前被执行程序,取出之后要删除队首,因为unlock的时候要从阻塞队列取出一个程序直接放到等待队列的队首,所以不能只顾着执行当前的程序,结果没删除,那么unlock之后就可能把当前执行程序给挤到第二,所以取出一个程序执行要直接把它从队首删掉
剩下还有很多思路和需要注意的地方,但是都是看刘汝佳的翻译就没问题的,我就是那个unlock要从阻塞队列首取程序的时候没有判空所以卡了很久,因为阻塞队列这个时候是可能为空的,话说这就是一道模拟题,数据结构的比重真的很少,感觉跟第五章的stl没啥区别
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pa;
string s[1005][30];
int main() {
int t;
cin >> t;
while (t--) {
int n, t1, t2, t3, t4, t5, quota;
cin >> n >> t1 >> t2 >> t3 >> t4 >> t5 >> quota;
getchar();
int rec[1005] = {};
for (int i = 0; i < n; i++) {
string str;
int cnt = 0;
while (getline(cin, str)) {
s[i][cnt++] = str;
if (str == "end") break;
}
rec[i] = cnt;
}
deque<int> q1, q2;
for (int i = 0; i < n; i++) q1.pb(i);
int lock = 0;
int Hash[1005] = {};
map<char, int> mp;
for (int i = 0; i < 26; i++) mp['a' + i] = 0;
while (!q1.empty()) {
int now = q1.front();
q1.pop_front();
int time = quota;
int p = Hash[now];
int flag = 1;
while (time > 0) {
if (s[now][p][1] == ' ') {
char ch = s[now][p][0];
mp[ch] = stoi(s[now][p].substr(4, sz(s[now][p]) - 4));
time -= t1;
p++;
} else if (s[now][p][0] == 'p') {
cout << now + 1 << ": " << mp[s[now][p][6]] << endl;
time -= t2;
p++;
} else if (s[now][p][0] == 'l') {
if (lock == 0) {
lock = 1;
time -= t3;
p++;
} else {
q2.pb(now);
flag = 0;
break;
}
} else if (s[now][p][0] == 'u') {
lock = 0;
if (!q2.empty()) {
q1.push_front(q2.front());
q2.pop_front();
}
time -= t4;
p++;
} else {
time -= t5;
p++;
break;
}
}
Hash[now] = p;
if (flag && p < rec[now]) q1.pb(now);
}
if (t) cout << endl;
}
return 0;
}