UVA210 并行程序模拟 Concurrency Simulator

考察:模拟,双端队列

这道题卡了我不少时间,题目里面有两个队列,一个等待队列一个阻塞队列,什么时候会有程序进入阻塞队列呢,就是已经有程序执行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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值