UVA210 并行程序模拟 Concurrency Simulator——一次非常失败的刷题经历

坑爹的题目,难道是我想多了吗。

题意翻译(来源洛谷)

你的任务是模拟至多10个程序(按输入顺序编号1~n)的并行执行。每个程序包含不超过25条语句。

格式一共是5种:赋值(var=constant),打印(print var),lock,unlock,end,耗时分别t1​,t2​,t3​,t4​,t5​。

变量用一个小写字母表示,初始时为0,为所有并行程序共有,且它的值始终保持在[0,100]内,所以一个程序对某一个变量的赋值会影响到另外一个程序。

每个时刻只能是一个程序处于运行状态,其他程序处于等待状态。运行状态之中的的程序每次最多分配Q个单位时间,一旦在未执行完程序时超过分配时间,这个程序则会被插入等待队列,然后从其的队首取出一共程序继续执行。而初始的等待队列为按照输入程序排入。

但是由于lock和unlock命令的出现,这个顺序会被改变。

lock的作用是申请对所有变量的独占访问,unlock则是解除对所有变量的独占访问,且它们一定成对出现。当一个程序已经对所有的变量独占访问后,其他程序若试图执行lock,无论其是否耗尽分配时间,都会被放在一个阻止队列的尾部,且当那个程序解除的时候,则会从阻止队列的头部的程序进入等待队列的头部。

现在给出n,t1​,t2​,t3​,t4​,t5​,Q以及n个程序,你需要输出所有print命令执行输出的值。


吐槽

原题中的英语有几个需要注意的点,一是 Any instruction currently being executed when the time quantum expires will be allowed to complete。 即只要在执行中的任务,哪怕时间到了也会接着执行。不过这个是比较好理解的。如果超时就停止执行的话,会TLE。

另一是The lock and unlock statements are used whenever a program wishes to claim mutually exclusive access to the variables it is manipulating。既然lock和unlock是用于变量的互斥访问的,那么一旦程序lock之后其他程序应该不能改变变量值。但是以上只是我个人的理解=。=  实际上题目并没有这么说,程序lock之后其它程序依然可以改变变量值,打印当然更没问题。只有执行lock才会阻塞,真的坑。

理解这一点后发现自己的程序过于冗余,不过懒得改了。

还有一点是输入The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs。 即有个数据组数的输入,但是在测试样例中并没有体现。还有输出的时候最后一组输出不能带多余的空格不然会PE、

Devcpp也是坑啊,居然给我跳出来另一个程序的运行窗口,怪不得de不出来bug。就这些点,这么简单一题浪费了我一天的时间= =、  sad


思路

很简单,两个队列,一个阻塞队列用queue实现,就绪队列由于有从头部插入,所以用deque实现。程序用vector啊数组啊实现都无所谓,我这边用queue实现了= =。代码很烂,无所谓了。

#include<iostream>
#include<string>
#include<vector>
#include<deque>
#include<queue>
using namespace std;

void solve(){
    int t[6];
    int n, q;
    cin >> n;
    for(int i = 1; i <= 5; i++)
        cin >> t[i];
    cin >> q;
    queue<int> bq;
    deque<int> rq;
    queue<string> program[12];
    int v[31] = {0};
    bool locked = false;
    int locking = 0;

    int pro = 1;
    string line;
    while(pro <= n){
        getline(cin,line);
        if (line.empty())
            continue;
        program[pro].push(line);
        if(line == "end")
            pro++;
    }
    
    for(int i = 1; i <= n; i++)
        rq.push_back(i);

    while(!rq.empty()){
        pro = rq.front();
        rq.pop_front();

        int time = q;
        int type = 0;
        bool flag = false;
        queue<string> &cur_pro = program[pro];
        while(time > 0)
        {
            if(cur_pro.empty()){ 
                flag = true; 
				break;
       		}
			
            string ins = cur_pro.front();
            
            //cout << pro << "  " << time << "  " << ins <<endl;
            
            if(ins[2] == '=')
                type = 1;
            else if (ins[1] == 'r')
                type = 2;
            else if (ins == "lock")
                type = 3;
            else if (ins == "unlock")
                type = 4;
            else if (ins == "end")
                type = 5;

            if(type == 5){
                cur_pro.pop();
                flag = true;
                break;
            }
            if(type == 3 && locked){
                bq.push(pro);
                flag = true;
                break;
            }
			
			
            cur_pro.pop();
            if(type == 1){
                int num = (ins.length() == 6 ? 10 * (ins[4]-'0') + ins[5] - '0' : ins[4] - '0');
                v[ins[0]-'a'] = num;
            }
            else if(type == 2){
                cout << pro << ": " << 	v[ins[6]-'a'] << endl;
            }
            else if(type == 3){
                locked = true;
                locking = pro;
            }
            else if(type == 4){
                locked = false;
                locking = 0;
                if(!bq.empty()){
                    int np = bq.front();
                    bq.pop();
                    rq.push_front(np);
                }
            }
            time -= t[type];
        }
        if(!flag)
            rq.push_back(pro);
    }
}

int main(){
    int T;
    cin >> T;
    bool f = false;
    while (T--)
    {
    	if(f)
    		cout << endl;
        solve();
        f = true;
    }
    return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值