UVa 210 Concurrency Simulator(双端队列)

题意  模拟程序并行运行

STL队列 双端队列 的应用  用双端队列维护即将执行的程序  再用个队列维护等待变量释放的程序   用lock表示变量锁定状态

先将所有程序依次放到执行队列中  每次取出队首程序运行不超过lim时间  未运行完又放到执行队列队尾

遇到lock时  若当前锁定状态为false就将锁定状态变为true  否则将当前程序放到等待队列队尾并结束运行

遇到unlock时  若等待队列有程序  就将等待队列队首程序放到执行队列队首

遇到end时 退出当前执行(不再进队尾)

#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
bool lock;
deque<int> qr;//执行队列
queue<int> qb;//等待队列
vector<string> prg[N];
string s;
int t[N], p[N], var[26], lim;

void run(int i)
{
    int rt = lim, v;
    string cur;
    while(rt > 0)
    {
        cur = prg[i][p[i]];
        if(cur[2] == '=')  // 赋值
        {
            rt -= t[0];
            v = cur[4] - '0';
            if(cur.size() == 6) v = v * 10 + cur[5] - '0';
            var[cur[0] - 'a'] = v;
        }
        else if(cur[2] == 'i')   //print
        {
            rt -= t[1];
            printf("%d: %d\n", i, var[cur[6] - 'a']);
        }
        else if(cur[2] == 'c')   //lock
        {
            rt -= t[2];
            if(lock)
            {
                qb.push(i);
                return;
            }
            else lock = true;
        }
        else if(cur[2] == 'l')  //unlock
        {
            lock = false;
            rt -= t[3];
            if(!qb.empty())
            {
                v = qb.front();
                qb.pop();
                qr.push_front(v);
            }
        }
        else return;  //end
        ++p[i];
    }
    qr.push_back(i);
}

int main()
{
    int cas, n;
    scanf("%d", &cas);
    while(cas--)
    {
        scanf("%d", &n);
        for(int i = 0; i < 5; ++i)
            scanf("%d", &t[i]);
        scanf("%d", &lim);

        for(int i = 1; i <= n; ++i)
        {
            prg[i].clear();
            while(getline(cin, s))
            {
                if(s == "") continue;
                prg[i].push_back(s);
                if(prg[i].back() == "end") break;
            }
            qr.push_back(i);
        }

        memset(p, 0, sizeof(p));
        memset(var, 0, sizeof(var));
        while(!qr.empty())
        {
            int cur = qr.front();
            qr.pop_front();
            run(cur);
        }
        if(cas) puts("");
    }
    return 0;
}

 Concurrency Simulator 

Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but in reality the single CPU alternates between the programs, executing some number of instructions
from each program before switching to the next. You are to simulate the concurrent execution of up to ten programs on such a system and determine the output that they will produce.

The program that is currently being executed is said to be running, while all programs awaiting execution are said to be ready. A program consists of a sequence of no more than 25 statements, one
per line, followed by an end statement. The statements available are listed below.

 

Each statement requires an integral number of time units to execute. The running program is permitted to continue executing instructions for a period of time called its quantum. When a program?s
time quantum expires, another ready program will be selected to run. Any instruction currently being executed when the time quantum expires will be allowed to complete.

Programs are queued first-in-first-out for execution in a ready queue. The initial order of the ready queue corresponds to the original order of the programs in the input file. This order
can change, however, as a result of the execution of lock and unlock statements.

The lock and unlock statements are used whenever a program wishes to claim mutually exclusive access to the variables it is manipulating. These statements always
occur in pairs, bracketing one or more other statements. A lock will always precede an unlock, and these statements will never be nested. Once a program successfully executes a lock statement, no other program
may successfully execute a lock statement until the locking program runs and executes the corresponding unlockstatement. Should a running program attempt to execute a lock while one is already in effect, this
program will be placed at the end of the blocked queue. Programs blocked in this fashion lose any of their current time quantum remaining. When an unlock is executed, any program at the head of the blocked queue is moved to the head
of the ready queue. The first statement this program will execute when it runs will be the lock statement that previously failed. Note that it is up to the programs involved to enforce the mutual exclusion protocol through correct usage of lock andunlock statements.
(A renegade program with no lock/unlock pair could alter any variables it wished, despite the proper use of lock/unlock by the other programs.)

Input

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.

The first line of the input file consists of seven integers separated by spaces. These integers specify (in order): the number of programs which follow, the unit execution times for each of the
five statements (in the order given above), and the number of time units comprising the time quantum. The remainder of the input consists of the programs, which are correctly formed from statements according to the rules described above.

All program statements begin in the first column of a line. Blanks appearing in a statement should be ignored. Associated with each program is an identification number based upon its location in
the input data (the first program has ID = 1, the second has ID = 2, etc.).

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

Your output will contain of the output generated by the print statements as they occur during the simulation. When a print statement is executed, your program should display the program ID, a colon,
a space, and the value of the selected variable. Output from separate print statements should appear on separate lines.

A sample input and correct output are shown below.

Sample Input

1

3 1 1 1 1 1 1
a = 4
print a
lock
b = 9
print b
unlock
print b
end
a = 3
print a
lock
b = 8
print b
unlock
print b
end
b = 5
a = 17
print a
print b
lock
b = 21
print b
unlock
print b
end

Sample Output

1: 3
2: 3
3: 17
3: 9
1: 9
1: 9
2: 8
2: 8
3: 21
3: 21

时间: 2024-10-05 04:45:24

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

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

题意:给定n个程序,每种程序有五种操作,分别为 var = constant(赋值),print var (打印), lock, unlock,end. 变量用小写字母表示,初始化为0,为程序所公有(一个程序里对某个变量修改可以会影响其他程序里的这个变量), 常数小于100(也就是说最多两位数). 每个时刻都只能有一个程序处于运行状态,其他的都在等待,上述五种操作用时分别是t1, t2, t3, t4, t5.运行中的程序, 每次最多能运行q个时间,当q个时间被用完后,它会被放在等待队列的尾部,

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]内,所以一个程序对某一个变量

UVA - 442 Matrix Chain Multiplication 双端队列

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

8、泛型程序设计与c++标准模板库2.3双端队列容器

双端队列容器是一种放松了访问权限的队列.除了从队列的首部和尾部访问元素外,标准的双端队列也支持通过使用下标操作符"[]"进行直接访问. 它提供了直接访问和顺序访问方法.其头文件为<deque>. 1)双端队列容器的构造函数 有4中形式的构造函数: deque();//构造size()为0的双端队列容器 deque(size_type n,const T& v=T());//初始化大小为n的双端队列,第二个参数是每个元素的初始值,默认为T()构造的对象 deque(c

习题3.26双端队列

#include<stdio.h> #include<stdlib.h> struct Node; struct Queue; typedef struct Node * PtrToNode; typedef struct Queue * PtrToQ; struct Node{ PtrToNode Pre; PtrToNode Next; ElemenType Ele; } struct Queue{ PtrToNode front; PtrToNode rear; }; Ptr

nyoj1117 鸡蛋队列 (双端队列,deque)

题目1117 题目信息 运行结果 本题排行 讨论区 鸡蛋队列 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 将两根筷子平行的放在一起,就构成了一个队列.将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop).但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入:对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来. 将①.②入队: 头____________尾                         ___

算法导论之八(10.1-5单数组实现双端队列)

算法导论第三版P131 题目: 10.1-5 栈插入和删除元素只能在同一端进行,队列的插入操作和删除操作分别在两端进行,与它们不同的,有一种双端队列(deque),其插入和删除操作都可以在两端进行.写出4个时间均为O(1)的过程,分别实现在双端队列插入和删除元素的操作,该队列使用一个数组实现的. 注意点: 1.左右端点指向的位置是类似于队列中的tail端点,是下一个插入操作的位置. 2.然后注意遍历的时候,左端点和右端点的位置关系,有两种可能,所以遍历的方式不一样. 代码: /* * 使用单数组

HDU 4286 Data Handler (双端队列)

Data Handler Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2455    Accepted Submission(s): 616 Problem Description You are in charge of data in a company, so you are called "Data Handler&qu

队列的应用:双端队列

双端队列(Deque:double ended queue)就是一个两端都是结尾的队列.队列的每一端都可以插入数据项和移除数据项.相对于普通队列,双端队列的入队和出队操作在两端都可进行. 双端队列的示意图: left:左端    right:右端 这里我们使用最常用的顺序结构来存储双端队列,为了节省空间,把它首尾相连,构成循环队列.并且规定left指向左端的第一个元素,right指向右端的下一个位置.那么队空的判断则是left==right,队满是(left-1+MAX)%MAX==right或