• 程序模拟(Concurrency Simulator, ACM/ICPC World Finals 1991, UVa210)rust解法


    你的任务是模拟n个程序(按输入顺序编号为1~n)的并行执行。每个程序包含不超过25条语句,格式一共有5种:var = constant(赋值);print var(打印);lock;unlock;end。
    变量用单个小写字母表示,初始为0,为所有程序公有(因此在一个程序里对某个变量赋值可能会影响另一个程序)。常数是小于100的非负整数。
    每个时刻只能有一个程序处于运行态,其他程序均处于等待态。上述5种语句分别需要t1、t2、t3、t4、t5单位时间。运行态的程序每次最多运行Q个单位时间(称为配额)。当一个程序的配额用完之后,把当前语句(如果存在)执行完之后该程序会被插入一个等待队列中,然后处理器从队首取出一个程序继续执行。初始等待队列包含按输入顺序排列的各个程序,但由于lock/unlock语句的出现,这个顺序可能会改变。
    lock的作用是申请对所有变量的独占访问。lock和unlock总是成对出现,并且不会嵌套。lock总是在unlock的前面。当一个程序成功执行完lock指令之后,其他程序一旦试图执行lock指令,就会马上被放到一个所谓的阻止队列的尾部(没有用完的配额就浪费了)。当unlock执行完毕后,阻止队列的第一个程序进入等待队列的首部。
    输入n, t1, t2, t3, t4, t5, Q以及n个程序,按照时间顺序输出所有print语句的程序编号和结果。

    样例:
    输入

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    输出

    1: 3
    2: 3
    3: 17
    3: 9
    1: 9
    1: 9
    2: 8
    2: 8
    3: 21
    3: 21
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    解法:

    use std::collections::{HashMap, VecDeque};
    use std::io;
    
    fn main() {
        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        let v: Vec<usize> = buf.split_whitespace().map(|x| x.parse().unwrap()).collect();
        let n = v[0];
        let q = v[6];
        let mut programs = vec![];
        for _i in 0..n {
            let mut prog_stats = vec![];
            loop {
                let mut buf = String::new();
                io::stdin().read_line(&mut buf).unwrap();
                let mut run_time = 0;
                if let Some(_idx) = buf.find('=') {
                    run_time = v[1];
                } else if buf.starts_with("print") {
                    run_time = v[2];
                } else if buf.starts_with("lock") {
                    run_time = v[3];
                } else if buf.starts_with("unlock") {
                    run_time = v[4];
                } else if buf.starts_with("end") {
                    run_time = v[5];
                }
                prog_stats.push((buf.trim().to_string(), run_time));
                if buf.trim() == "end" {
                    programs.push(prog_stats);
                    break;
                }
            }
        }
        let mut wait_progs = VecDeque::new();
        for i in 0..n {
            wait_progs.push_back((i, 0, 0));
        }
        let mut block_progs = VecDeque::new();
        let mut lock = (false, 0);
        let mut vars = HashMap::new();
        while let Some(mut prg) = wait_progs.pop_front() {
            let mut run_time = q;
            while run_time > 0 {
                let statement = &programs[prg.0][prg.1].0;
                if statement.starts_with("lock") {
                    if lock.0 == true && lock.1 != prg.0 {
                        block_progs.push_back(prg);
                        break;
                    } else {
                        lock.0 = true;
                        lock.1 = prg.0;
                    }
                } else if statement.starts_with("unlock") {
                    lock.0 = false;
                    lock.1 = 0;
                    if let Some(prg) = block_progs.pop_front() {
                        wait_progs.push_front(prg);
                    }
                } else if let Some(idx) = statement.find('=') {
                    let var = statement[0..idx - 1].to_string();
                    let value: usize = statement[idx + 2..].parse().unwrap();
                    vars.insert(var, value );
                } else if statement.starts_with("print") {
                    let var = statement[6..].to_string();
                    println!("{}: {}", prg.0 + 1, vars.get(&var).unwrap());
                }
                let min_time = (programs[prg.0][prg.1].1 - prg.2).min(run_time);
                prg.2 += min_time;
                run_time -= min_time;
                if prg.2 < programs[prg.0][prg.1].1 {
                    wait_progs.push_back(prg);
                } else if prg.1 < programs[prg.0].len() - 1 {
                    prg.1 += 1;
                    prg.2 = 0;
                    if run_time == 0 {
                        wait_progs.push_back(prg);
                    }
                } else {
                    break;
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
  • 相关阅读:
    Web3风口吹到出版业 Paragraph如何打造全新的内容自营模式?
    uniapp数据点击的时候将数据存入同一个本地存储中并且最大限度5个
    javaIO流06:节点流和处理流(包装流)(以代码的方式简单理解处理流的装饰者模式)
    MySQL主从复制
    【JSP】Page指令和九大内置对象
    AI 模型社区“魔搭”亮相,平头哥又上新,端云一体生态再升级
    泛微E8事务回滚类
    【C++学习】类与对象(下)
    Shiro框架详解
    python3:split()分割字符串为字符/字符串列表 2023-11-20
  • 原文地址:https://blog.csdn.net/inxunxun/article/details/134084432