UVA210 Concurrent Simulator

并行程序模拟 Concurrency Simulator

题目描述

你的任务是模拟 n n n个程序(按输入顺序编号 1 1 1~ n n n)的并行执行。每个程序包含不超过25条语句。

格式一共是5种:赋值( v a r = c o n s t a n t var=constant var=constant),打印(print v a r var var), l o c k lock lock u n l o c k unlock unlock e n d end end,耗时分别为 t 1 , t 2 , t 3 , t 4 , t 5 t_1,t_2,t_3,t_4,t_5 t1,t2,t3,t4,t5

变量用一个小写字母表示,初始时为 0 0 0,为所有并行程序共有,且它的值始终保持在 [ 0 , 100 ] [0,100] [0,100] 内,所以一个程序对某一个变量的赋值会影响到另外一个程序。

每个时刻只能是一个程序处于运行状态,其他程序处于等待状态。运行状态之中的的程序每次最多分配 Q Q Q 个单位时间,一旦在未执行完程序时超过分配时间,这个程序则会被插入等待队列,然后从其的队首取出一共程序继续执行。而初始的等待队列为按照输入程序排入。

但是由于 l o c k lock lock u n l o c k unlock unlock 命令的出现,这个顺序会被改变。

l o c k lock lock 的作用是申请对所有变量的独占访问, u n l o c k unlock unlock 则是解除对所有变量的独占访问,且它们一定成对出现。当一个程序已经对所有的变量独占访问后,其他程序若试图执行 l o c k lock lock,无论其是否耗尽分配时间,都会被放在一个阻止队列的尾部,且当那个程序解除的时候,则会从阻止队列的头部的程序进入等待队列的头部

现在给出 n , t 1 , t 2 , t 3 , t 4 , t 5 , Q n,t_1,t_2,t_3,t_4,t_5,Q n,t1,t2,t3,t4,t5,Q 以及 n n n 个程序,你需要输出所有 p r i n t print print 命令执行输出的值。

输入格式

第一行数据组数
第二行空行
第三行分别是n t1 t2 t3 t4 t5 Q用空格隔开
下面是n段程序,每组数据的程序用空行隔开

样例 #1

样例输入 #1

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

样例输出 #1

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

分析

题目是洛谷翻译的,它原本的样例输入和输出有一点问题,原题来源于UVA OJ平台.
题目关键信息已加粗,还有一点是,当时间配额不够用时,当存在语句时要把该语句执行完再加入等待队列.简单来说,就是剩余的时间>0但是小于执行该语句所需要的时间,那也要把该语句执行完.

思维难度不大,是一道模拟类的题目,这里用双端队列来模拟等待队列(就绪队列),使用普通队列来模拟阻止队列.

#include <deque>
#include <queue>
#include <string>
#include <map>
#include <iostream>
using namespace std;

typedef struct Program{
	int id;
	int point;
	string statements[30];
	
	Program(int id, int point):id(id), point(point){}
} Program;

void algo();

int n = 0;
int t1, t2, t3, t4, t5;
int Q = 0;

int main(int argc, char **argv)
{
	int times = 0;
	cin >> times;
	for(int i = 0; i < times; i++){
		cin >> n >> t1 >> t2 >> t3 >> t4 >> t5 >> Q;
		getchar();
		algo();
		if(i != times-1){
			cout << endl;
		}
	}
	return 0;
	
}
void algo(){
	deque<Program> wait;
	queue<Program> stop;
	map<char, string> vars;
	string end = "end";
	for(int i = 0; i < n; i++){
		Program program(i, 0);
		string statement;
		int count = 0;
		while(end.compare(statement) != 0){
			getline(cin, statement);
			program.statements[count++] = statement;
		}
		wait.push_back(program);
	}
	int lock = 0;
	while(!wait.empty()){
		Program p = wait.front();
		wait.pop_front();
		bool finished = false;
		bool stopped = false;
		int t = Q;
		while(t > 0){
			string s = p.statements[p.point];
			p.point++;
			if(s.compare("lock") == 0){
				if(lock == 1){
					stopped = true;
					p.point--;
					stop.push(p);
					break;
				}else{
					lock = 1;
					t -= t3;
				}
			}else if(s.compare("unlock") == 0){
				if(!stop.empty()){
					Program sp = stop.front();
					stop.pop();
					wait.push_front(sp);
				}
				t -= t4;
				lock = 0;
			}else if(s.substr(0, 5).compare("print") == 0){
				t -= t2;
				cout << p.id+1 << ": " << (vars[s[6]].compare("") == 0 ? "0" : vars[s[6]]) << endl;
			}else if(s.compare("end") == 0){
				finished = true;
				t -= t5;
				break;
			}else{
				vars[s[0]] = s.substr(4);
				t -= t1;
			}
		}
		if(!stopped && !finished){
			wait.push_back(p);
		}
	}
}

刚开始做的时候,按照洛谷的输入和输出格式,一直没有AC,翻了一下原网站才知道,给我整无语了:)
总来说,主要锻炼一下C++的STL库的运用,主要用到的数据结构是队列,另外也是用map来进行存储变量的值.
这里说到map当时也遇到一个问题,当时我的value设置的是string类型的,当我们使用下标语法访问map中的键值时,如果key不存在,则map会执行一个插值函数(insert),这个插入的默认值依据数据类型来确定,如果是内置的基本数据类型,那就是0,如果是string则为空串,当为我们自定义的类型时,默认值为我们内部默认提供的初始值.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值