zoukankan      html  css  js  c++  java
  • UVa 210 并行程序模拟(deque)

    题意:

    模拟n个程序运行

    格式一共有5种:var = constant(赋值);print var(打印);lock;unlock;end, 

    上述5种语句分别需
    要t1、t2、t3、t4、t5单位时间

    运行态的程序每次最多运行Q个单位时间(称为配额)

    一个程序的配额用完之后,把当前语句(如果存在)执行完之后该程序会被插入一个等待队
    中,然后处理器从队首取出一个程序继续执行。

    lock的作用是申请对所有变量的独占访问。lock和unlock总是成对出现,并且不会嵌套。
    lock总是在unlock的前面。当一个程序成功执行完lock指令之后,其他程序一旦试图执行lock
    指令,就会马上被放到一个所谓的阻止队列的尾部(没有用完的配额就浪费了)。当unlock
    执行完毕后,阻止队列的第一个程序进入等待队列的首部。

    输出运行程序的print

    分析:

    这道题题目很长,理解会有点困难, 没看过原题做的话会有挺多坑。

    1.executed when the time quantum expires will be allowed to complete.

    就是如果执行完当前指令后Q<0, 那么这个程序仍然可以运行, 之后就会结束运行

    2.独占访问我一开始理解为如果被一个程序lock了, 那么只有这个lock程序可以修改变量, 其实并不是, lock后其他程序仍然可以修改变量。

    3.那么这题就可以看成2个队列的模拟题了, 一个等待队列deque, 一个阻止队列queue。

    4.一开始将所有数据先输入一个数组中, 然后用一个数组记录每个程序的初始行号, 这样模拟会比较方面。

    5.找出不同指令的不同点, 用switch一次判断出来。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxl = 10000;
    char pg[maxl][10];
    int n, quan, locked,t[5], pgline[maxl];
    int val[26];
    deque<int> Wait;
    queue<int> Block;
    void run(int num)
    {
        int q = quan;
        while(q > 0){
            char *str = pg[pgline[num]];
            switch(str[2]){
                case '='://var
                    val[str[0] - 'a'] = isdigit(str[5]) ?(str[4] - '0') * 10 + str[5] - '0': str[4] - '0';
                    q -= t[0];
                    break;
                case 'i':// print
                    printf("%d: %d
    ", num + 1, val[str[6]-'a']);
                    q -= t[1];
                    break;
                case 'c': // lock
                    if(locked){
                        Block.push(num);
                        return;
                    }
                    locked = 1;
                    q -= t[2];
                    break;
                case 'l': // unlock
                    locked = 0;
                    if(!Block.empty()){
                        Wait.push_front(Block.front());
                        Block.pop();
                    }
                    q -= t[3];
                    break;
                case 'd': // end
                    return;
            }
            pgline[num] ++;
        }
        Wait.push_back(num);
    }
    
    int main()
    {   
        
        int T;
        scanf("%d", &T);
        while(T--){
            int line = 0;
            memset(pgline,0,sizeof(pgline));
            memset(pg,0,sizeof(pg));
            memset(val,0,sizeof(val));
            scanf("%d %d %d %d %d %d %d ", &n, &t[0], &t[1], &t[2], &t[3], &t[4], &quan);
            for(int i = 0; i < n; i++){
                gets(pg[line++]);
                pgline[i] = line - 1;
                while(pg[line-1][2] != 'd')
                    gets(pg[line++]);
    
                Wait.push_back(i);
            }
    
            locked = 0;
            while(!Wait.empty()){
                int pick = Wait.front();
                Wait.pop_front();
                run(pick);
            }
            if(T)
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    关于配置文件权衡,.config VS .xml
    Google不支持小于12px字体 终极办法
    两个表循环的复杂度分析 征集
    SQL 计算列
    5分钟上手写ECharts的第一个图表
    NGif, Animated GIF Encoder for .NET
    Chart系列(一):Chart的基本元素
    一张广告图片引起的思维DFS
    洛谷 P2580 于是他错误的点名开始了
    洛谷 P1496 火烧赤壁
  • 原文地址:https://www.cnblogs.com/Jadon97/p/7168442.html
Copyright © 2011-2022 走看看