洛谷-UVA210 并行程序模拟 Concurrency Simulator

ゞ 浴缸里的玫瑰 2023-06-12 11:30 166阅读 0赞

PDF

format_png

输入格式

format_png 1

输出格式

format_png 2

题意翻译

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

格式一共是5种:赋值(var=constantvar=constant),打印(print varvar),locklock,unlockunlock,endend,耗时分别为t_1,t_2,t_3,t_4,t_5t1​,t2​,t3​,t4​,t5​。

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

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

但是由于locklock和unlockunlock命令的出现,这个顺序会被改变。

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

现在给出n,t_1,t_2,t_3,t_4,t_5,Qn,t1​,t2​,t3​,t4​,t5​,Q以及nn个程序,你需要输出所有printprint命令执行输出的值。

输入输出样例

输入 #1复制

  1. 3 1 1 1 1 1 1
  2. a = 4
  3. print a
  4. lock
  5. b = 9
  6. print b
  7. unlock
  8. print b
  9. end
  10. a = 3
  11. print a
  12. lock
  13. b = 8
  14. print b
  15. unlock
  16. print b
  17. end
  18. b = 5
  19. a = 17
  20. print a
  21. print b
  22. lock
  23. b = 21
  24. print b
  25. unlock
  26. print b
  27. end

输出 #1复制

  1. 1: 3
  2. 2: 3
  3. 3: 17
  4. 3: 9
  5. 1: 9
  6. 1: 9
  7. 2: 8
  8. 2: 8
  9. 3: 21
  10. 3: 21
  11. #include<bits/stdc++.h>
  12. using namespace std;
  13. const int maxNum=1005;
  14. int n; //进程个数
  15. int times[5];//表示5个指令所花的时间
  16. int quantum;//时间片大小
  17. vector<string> prg[maxNum]; //并行程序个数,指令
  18. deque<int> readyQ;//就绪队列
  19. queue<int> blockQ;// 阻塞队列
  20. bool locked=false;//锁
  21. int val[26];//26个变量
  22. int p[maxNum];//进程运行在指令的位置
  23. void run(int i){
  24. int t=quantum;
  25. while(t>0){
  26. string cur; //指令
  27. cur=prg[i][p[i]];
  28. //赋值语句
  29. switch(cur[2]){
  30. case '=' : {
  31. t=t-times[0];
  32. int num;
  33. if(cur.size()==6){
  34. num=cur[4]*10-'0'+cur[5]-'0';
  35. }else{
  36. num=cur[4]-'0';
  37. }
  38. val[cur[0]-'a']=num-'0'; //赋值
  39. break;
  40. }
  41. case 'i':{//打印
  42. t=t-times[1];
  43. cout<<i+1<<": "<<val[cur[6]-'a'];
  44. break;
  45. }
  46. case 'c':{
  47. t=t-times[2];
  48. if(locked==false){//未锁
  49. blockQ.push(i);
  50. return; //结束此指令
  51. }else{
  52. locked=true;//上锁
  53. }
  54. break;
  55. }
  56. case 'l':{
  57. t=t-times[3];
  58. locked=false;//解锁
  59. if(!blockQ.empty()){
  60. int u=blockQ.front();
  61. blockQ.pop();
  62. readyQ.push_front(u);
  63. }
  64. break;
  65. }
  66. case 'd':{
  67. //不用写:t=t-times[4];
  68. break;
  69. }
  70. }
  71. p[i]++;//获取下一条指令
  72. }
  73. }
  74. int main(){
  75. int n;
  76. cin>>n;//T组用例
  77. for(int i=0;i<5;i++){
  78. cin>>times[i]; //每个指令所花时间
  79. }
  80. cin>>quantum;//时间片
  81. //读入n组指令集合
  82. for(int i=0;i<n;i++){
  83. string s;
  84. while(s!="end"){
  85. cin>>s;
  86. prg[i].push_back(s);
  87. }
  88. readyQ.push_back(i);//加入就绪队列
  89. }
  90. //执行 程序
  91. while(!readyQ.empty()){
  92. int pid=readyQ.front();// 获取就绪队列最前面的进程编号
  93. readyQ.pop_front();
  94. run(pid);
  95. }
  96. return 0;
  97. }

发表评论

表情:
评论列表 (有 0 条评论,166人围观)

还没有评论,来说两句吧...

相关阅读