UVa 210 Concurrency Simulator (双端队列+模拟)

题意:给定n个程序,每种程序有五种操作,分别为 var = constant(赋值),print var (打印), lock, unlock,end。

变量用小写字母表示,初始化为0,为程序所公有(一个程序里对某个变量修改可以会影响其他程序里的这个变量),

常数小于100(也就是说最多两位数)。

每个时刻都只能有一个程序处于运行状态,其他的都在等待,上述五种操作用时分别是t1, t2, t3, t4, t5。运行中的程序,

每次最多能运行q个时间,当q个时间被用完后,它会被放在等待队列的尾部,然后再从首部取出一个程序运行,初始等待队列按输入顺序,

但是lock和unlock会改变顺序,它们总是成对出现,不会出现嵌套。如果某个程序已经执行了lock,后面还有程序执行lock,

那么这个程序就会马上被放到一个阻止队列的尾部(当然如果运行时间还没用完也就浪费了)。当unlock结束后,阻止队列中的第一个程序进入等待队列的首部。

问你程序的运行结果是什么,输出格式是第几个程序加冒号加空格加结果,两个相连的数据用空行隔开。

析:这个题主要是看懂题意,如果看懂题意,那么就比较简单了,首先是题目中多次出现队列,并且还放在首部,那么就可以知道应该是双端队列,

我们使用STL里面的,也可以自己写一个,并不难写,其他的就是模拟这个,没有什么难度,要注意的是,在结束inlock从阻止队列中拿出放在等待队列时,

要考虑是不是已经空了,否则可能使程序崩溃。

代码如下:

#include <iostream>
#include <cstdio>
#include <queue>
#include <deque>
#include <vector>
#include <cstring>

using namespace std;
const int maxn = 1024;
deque<int> wait;
queue<int> block;
vector<string> pram[maxn];
int t[6], Q, cnt[maxn], val[30];
bool lock;

void run(int i){
    int q = Q;
    string s;
    while(q > 0){
        s = pram[i][cnt[i]];
        if(‘=‘ == s[2]){
            int num = s[4] - ‘0‘;
            q -= t[1];
            if(6 == s.size())  num = 10 * num + s[5] - ‘0‘;
            val[s[0]-‘a‘] = num;
        }
        else if(‘i‘ == s[2]){
            q -= t[2];
            printf("%d: %d\n", i, val[s[6]-‘a‘]);
        }
        else if(‘c‘ == s[2]){
            q -= t[3];
            if(lock){
                block.push(i);
                return ;
            }
            else lock = true;
        }
        else if(‘l‘ == s[2]){
            q -= t[4];
            lock = false;
            if(!block.empty()){
                wait.push_front(block.front());
                block.pop();
            }
        }
        else return ;
        ++cnt[i];
    }
    wait.push_back(i);
}

int main(){
    int T, n;  cin >> T;
    while(T--){
        scanf("%d", &n);
        for(int i = 0; i < 5; ++i)  scanf("%d", &t[i+1]);
        scanf("%d", &Q);
        getchar();
        string s;
        for(int i = 1; i <= n; ++i)  pram[i].clear();
        for(int i = 1; i <= n; ++i){
            while(true){
                getline(cin, s);
                pram[i].push_back(s);
                if(s == "end")  break;
            }
            wait.push_back(i);
        }

        memset(cnt, 0, sizeof(cnt));
        memset(val, 0, sizeof(val));
        lock = false;
        while(!wait.empty()){
            int p = wait.front();  wait.pop_front();
            run(p);
        }
        if(T)  printf("\n");
    }
    return 0;
}
时间: 2025-01-02 00:15:44

UVa 210 Concurrency Simulator (双端队列+模拟)的相关文章

UVa 210 Concurrency Simulator(双端队列)

题意  模拟程序并行运行 STL队列 双端队列 的应用  用双端队列维护即将执行的程序  再用个队列维护等待变量释放的程序   用lock表示变量锁定状态 先将所有程序依次放到执行队列中  每次取出队首程序运行不超过lim时间  未运行完又放到执行队列队尾 遇到lock时  若当前锁定状态为false就将锁定状态变为true  否则将当前程序放到等待队列队尾并结束运行 遇到unlock时  若等待队列有程序  就将等待队列队首程序放到执行队列队首 遇到end时 退出当前执行(不再进队尾) #in

【SGU】271. Book Pile(双端队列模拟)

一摞书,2个操作,一个操作是在书堆上加一本,第二个将前K个书翻转 看别人用Splay树做的,但是可以用双端队列模拟,因为K个书之后的书位置已经定下来了,所以只需要记录在队列头加书还是尾加书 #include<cstdio> #include<string> #include<algorithm> #include<queue> #include<stack> #include<cstring> #include<iostream

hdu-5929 Basic Data Structure(双端队列+模拟)

题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 207    Accepted Submission(s): 41 Problem Description Mr. Frog learned a basic data structure recently, which is called

UVA 210 Concurrency Simulator

题目链接:https://vjudge.net/problem/UVA-210 题目大意 一共有 T 组案例. 对于每组案例,你的任务是模拟n个程序(按输入顺序编号1~n)的并行执行.每个程序包含不超过25条语句. 格式一共是5种:赋值(var=constant),打印(print var),lock,unlock,end,耗时分别为$t_1,t_2,t_3,t_4,t_5$?. 变量用一个小写字母表示,初始时为0,为所有并行程序共有,且它的值始终保持在[0,100]内,所以一个程序对某一个变量

lintcode 二叉树的锯齿形层次遍历 (双端队列)

题目链接: http://www.lintcode.com/zh-cn/problem/binary-tree-zigzag-level-order-traversal/ 二叉树的锯齿形层次遍历 给出一棵二叉树,返回其节点值的锯齿形层次遍历(先从左往右,下一层再从右往左,层与层之间交替进行) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 返回其锯齿形的层次遍历为: [ [3], [20,9], [15,7] ] 思路: 我们用双端队列模拟一下这个过程

【BZOJ2457】[BeiJing2011]双端队列 贪心+模拟

[BZOJ2457][BeiJing2011]双端队列 Description Sherry现在碰到了一个棘手的问题,有N个整数需要排序. Sherry手头能用的工具就是若干个双端队列. 她需要依次处理这N个数,对于每个数,Sherry能做以下两件事: 1.新建一个双端队列,并将当前数作为这个队列中的唯一的数: 2.将当前数放入已有的队列的头之前或者尾之后. 对所有的数处理完成之后,Sherry将这些队列排序后就可以得到一个非降的序列. Input 第一行包含一个整数N,表示整数的个数.接下来的

Java 模拟队列(一般队列、双端队列、优先级队列)

队列: 先进先出,处理类似排队的问题,先排的.先处理,后排的等前面的处理完了,再处理 对于插入和移除操作的时间复杂度都为O(1).从后面插入,从前面移除 双端队列: 即在队列两端都能够insert和remove:insertLeft.insertRight.removeLeft.removeRight 含有栈和队列的功能,如去掉insertLeft.removeLeft,那就跟栈一样了.如去掉insertLeft.removeRight.那就跟队列一样了 一般使用频率较低,时间复杂度 O(1)

UVA - 442 Matrix Chain Multiplication 双端队列

题目大意:给出n个矩阵和表达式,问该表达式是否正确,如果计算正确,输出计算了多少次 解题思路:双端队列,遇到右括号时弹出后面的两个矩阵进行乘法,相乘时要注意顺序,是第二个出队列的乘上第一个出队列的. #include<cstdio> #include<algorithm> #include<deque> #include<map> #include<cstring> using namespace std; #define maxn 50010

补番计划 (长沙理工大学第十一届程序设计竞赛)(双端队列+set容器+string)

补番计划 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 8   Accepted Submission(s) : 1 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 阿聪是一个日漫狂魔.暑假在家的时候,他有12小时在补番,12小时在睡