Concurrency Simulator

Time limit:3000ms

Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but in reality the single CPU alternates between the programs, executing some number of instructions from each program before switching to the next. You are to simulate the concurrent execution of up to ten programs on such a system and determine the output that they will produce.
The program that is currently being executed is said to be running, while all programs awaiting execution are said to be ready. A program consists of a sequence of no more than 25 statements, one per line, followed by an end statement. The statements available are listed below.
Statement Type Assignment Output Begin Mutual Exclusion End Mutual Exclusion Stop Execution Syntax variable = constant print variable lock unlock end
A variable is any single lowercase alphabetic char- acter and a constant is an unsigned decimal num- ber less than 100. There are only 26 variables in the computer system, and they are shared among the programs. Thus assignments to a variable in one program affect the value that might be printed by a different program. All variables are initially set to zero.
Each statement requires an integral number of time units to execute. The running program is permitted to continue executing instructions for a period of time called its quantum. When a program’s time quantum expires, another ready program will be selected to run. Any instruction currently being executed when the time quantum expires will be allowed to complete.
Programs are queued first-in-first-out for execution in a ready queue. The initial order of the ready queue corresponds to the original order of the programs in the input file. This order can change, however, as a result of the execution of lock and unlock statements.
The lock and unlock statements are used whenever a program wishes to claim mutually exclusive access to the variables it is manipulating. These statements always occur in pairs, bracketing one or more other statements. A lock will always precede an unlock, and these statements will never be nested. Once a program successfully executes a lock statement, no other program may successfully execute a lock statement until the locking program runs and executes the corresponding unlock statement. Should a running program attempt to execute a lock while one is already in effect, this program will be placed at the end of the blocked queue. Programs blocked in this fashion lose any of their current time quantum remaining. When an unlock is executed, any program at the head of the blocked queue is moved to the head of the ready queue. The first statement this program will execute when it runs will be the lock statement that previously failed. Note that it is up to the programs involved to enforce the mutual exclusion protocol through correct usage of lock and unlock statements. (A renegade program with no lock/unlock pair could alter any variables it wished, despite the proper use of lock/unlock by the other programs.)

Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
The first line of the input file consists of seven integers separated by spaces. These integers specify (in order): the number of programs which follow, the unit execution times for each of the five statements (in the order given above), and the number of time units comprising the time quantum. The remainder of the input consists of the programs, which are correctly formed from statements according to the rules described above.
All program statements begin in the first column of a line. Blanks appearing in a statement should be ignored. Associated with each program is an identification number based upon its location in the input data (the first program has ID = 1, the second has ID = 2, etc.).

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.
Your output will contain of the output generated by the print statements as they occur during the simulation. When a print statement is executed, your program should display the program ID, a colon, a space, and the value of the selected variable. Output from separate print statements should appear on separate lines.

Sample Input

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

Sample Output

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


题意

        模拟n个程序(按照序号1-n并行执行)。每个程序包含不超过25条语句,有5种格式。5条语句每条语句都有执行时间,每个程序都有配额时间,如果用完就要结束并放到运行队列的队尾,如果一个程序处于lock时,其他程序如果要执行lock就要放入等待队列中,当一个程序执行unlock时就要从等待队列中取出第一个程序放到执行队列的首部。输入n,t1,t2,t3,t4,t5,t以及n个程序,按照时间顺序输出所有的print的结果。

思路

        使用双端队列来模拟这个程序就可以了,但是有一个坑点,就是在配额小于下一条语句需要的时间且配额大于0的时候还是可以执行这条语句的!!!我一开始理解成了配额只要小于下一条语句需要的时间就不能执行而TLE。还有就是要注意输出!!
        学到了deque。美滋滋。


代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
using namespace std;

typedef long long ll;

struct opi {
    int type;
    int num;
    int val;
};

int n, T;
int tm[6];          //语句耗时
int poi[10005];     //每个程序需要运行的语句
int vle[30];        //变量
opi ar[10005][30];  //所有程序的语句存放

deque<int> nw;
deque<int> wt;

bool bul;

int main () {
    int t;
    scanf("%d", &t);
    while (t--) {
        bul = 0;
        nw.clear();
        wt.clear();
        memset(vle, 0, sizeof(vle));
        scanf("%d %d %d %d %d %d %d", &n, &tm[1], &tm[2], &tm[3], &tm[4], &tm[5], &T);
        getchar();
        for (int i = 1; i <= n; ++i) {
            poi[i] = 1;
            int v = 0;
            string str;
            do {
                getline(cin, str);
                if (str[2] == '=') {
                    int len = str.length();
                    int res = 0;
                    for (int j = 4; j < len; ++j) {
                        res *= 10;
                        res += str[j]-'0';
                    }
                    ar[i][++v].type = 1;
                    ar[i][v].num = str[0]-'a';
                    ar[i][v].val = res;
                }
                else if (str[0] == 'l' && str[1] == 'o') {
                    ar[i][++v].type = 3;
                }
                else if (str[0] == 'u' && str[1] == 'n') {
                    ar[i][++v].type = 4;
                }
                else if (str[0] == 'e' && str[1] == 'n') {
                    ar[i][++v].type = 5;
                }
                else {
                    ar[i][++v].type = 2;
                    ar[i][v].num = str[6]-'a';
                }
            } while (!(str[0] == 'e' && str[1] == 'n'));
            nw.push_back(i);
        }
        while (!nw.empty()) {
            int v = nw.front();
            nw.pop_front();
            int et = T;
            bool in = 1;
            while (et > 0) {
                if (ar[v][poi[v]].type == 1) {
                    vle[ar[v][poi[v]].num] = ar[v][poi[v]].val;
                    poi[v]++;
                    et -= tm[1];
                }
                else if (ar[v][poi[v]].type == 2) {
                    cout << v << ": " << vle[ar[v][poi[v]].num] << '\n';
                    poi[v]++;
                    et -= tm[2];
                }
                else if (ar[v][poi[v]].type == 3) {
                    if (bul) {
                        wt.push_back(v);
                        in = 0;
                        break;
                    }
                    else {
                        bul = 1;
                        poi[v]++;
                        et -= tm[3];
                    }
                }
                else if (ar[v][poi[v]].type == 4) {
                    bul = 0;
                    if (!wt.empty()) {
                        nw.push_front(wt.front());
                        wt.pop_front();
                    }
                    poi[v]++;
                    et -= tm[4];
                }
                else if (ar[v][poi[v]].type == 5) {
                    in = 0;
                    et -= tm[5];
                    break;
                }
            }
            if (in) {
                nw.push_back(v);
            }
        }
        if (t) {
            cout << '\n';
        }
    }
    return 0;
}

发表评论