/* 1996 ACM Finals Problem D, Bang the Drum Slowly Ed Karrels, December 1996 */ #include enum InstType {TERMINAL, UNCOND, COND}; typedef struct { enum InstType type; int next_1, next_2; } Instruction; float Execute(int n, int t, Instruction instr[], int pos); int Time_RotateTo(int from, int to, int n); int main() { Instruction instr[51]; int n, t, c=1; int addr; InstType type; float runtime; // loop until n and t are 0 while (scanf("%d %d", &n, &t), n && t) { // loop until instruction address 0 // store each instruction at the specified address in // 'instr[]' while (scanf("%d", &addr), addr) { // read in the instruction scanf("%d", &type); instr[addr].type = type; if (type > TERMINAL) { scanf("%d", &instr[addr].next_1); if (type == COND) { scanf("%d", &instr[addr].next_2); } } } runtime = Execute(n, t, instr, 1); printf("Case %d. Execution time = %.4f\n", c++, runtime); } return 0; } float Execute(int n, int t, Instruction instr[], int pos) { // set 'ins' to point to current instruction Instruction *ins = instr + pos; int time = 1 + t; // 1 time unit needed to read instruction // t units to execute int time1, time2; pos += 1 + t; // move past the instruction, and rotate // for the time it takes to execute pos = ((pos - 1) % n) + 1; // make sure 1 <= pos <= n switch (ins->type) { case TERMINAL: return time; case UNCOND: // figure the time needed to rotate to next instruction time += Time_RotateTo(pos, ins->next_1, n); // figure time to execute from next instruction onward time += Execute(n, t, instr, ins->next_1); return time; case COND: // figure the time needed to rotate to // either of the next two instructions, // and how long it will take to execute the program // from that point onward time1 = Time_RotateTo(pos, ins->next_1, n) + Execute(n, t, instr, ins->next_1); time2 = Time_RotateTo(pos, ins->next_2, n) + Execute(n, t, instr, ins->next_2); // take the average of the two times return time + (time1 + time2) / 2.0; } return 0; } int Time_RotateTo(int from, int to, int n) { if (to < from) { return n - (from - to); } else { return to - from; } }