当前位置: 首页 > article >正文

程序模拟(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: 3
2: 3
3: 17
3: 9
1: 9
1: 9
2: 8
2: 8
3: 21
3: 21

解法:

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;
            }
        }
    }
}

http://www.kler.cn/news/108986.html

相关文章:

  • java集合之List接口实现类常用方法详解
  • Gitee 发行版
  • 【音视频】Linux | FFmpeg源码搭建
  • explain查询sql执行计划返回的字段的详细说明
  • LeetCode——哈希表(Java)
  • uni-app中tab选项卡的实现效果 @click=“clickTab(‘sell‘)“事件可传参数
  • No175.精选前端面试题,享受每天的挑战和学习
  • 【算法与数据结构】--算法应用--算法和数据结构的案例研究
  • ubuntu部署个人网盘nextCloud使用docker-compose方式
  • 性能优化必读 | AntDB-M高性能设计之线程池协程模型
  • Docker底层原理:Cgroup V2的使用
  • centos7 部署 Flink
  • 设计模式——单例模式详解
  • 随笔:使用Python爬取知乎上相关问题的所有回答
  • 【CSS】伪类和伪元素
  • C#WPFPrism框架导航应用实例
  • sprinbboot 2.7启动不生成日志文件
  • 电子电器架构 —— 车载网关初入门(二)
  • 【C++代码】爬楼梯,不同路径,整数拆分,不同搜索树,动态规划--代码随想录
  • 泰州市旅游景点门票预订管理系统 vue+uniapp微信小程序
  • C#:枚举是命名的整形常量的集合
  • 什么是 Node.js
  • ESM蛋白质语言模型系列
  • 202310-MetaPhlAn4安装和使用方法-Anaconda3- centos9 stream
  • Anaconda下载和安装
  • hdlbits系列verilog解答(8位宽移位寄存器)-24
  • LangChain+LLM实战---BERT主要的创新之处和注意力机制中的QKV
  • MyBatis-Plus 实战教程四 idea插件
  • IP地址与代理ip在网络安全中的关键作用
  • 震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)