#include #include #include #include #include #include using namespace std; /* * A pair of numbers to represent the total hold time for any given condition. * The "first" time is the hold if the condition is true; the "second" time is * the hold if the condition is false. */ typedef pair hold_t; /* * A "HOLD n IF xxx" statement and "HOLD m IF NOT xxx" statement within the * same data set and for the same named condition "xxx" are mutually exclusive. * Therefore, the minimum hold time for such a pair of statements is min(n,m) * and the maximum hold time for the pair is max(n,m). * * This data structure maps each named condition to its total true and false * hold times. If there are multiple "IF xxx" statements for the same * condition, the hold times for all of these are summed together into a single * true hold total for this condition. Likewise multiple "IF NOT xxx" hold * times are summed into a single false hold total. */ typedef map cond_t; /* A single command: (time t of this command, command text) */ typedef pair cmd_t; /* The list of all commands in a single data set */ typedef vector dataset_t; /* Main body of program */ void process(void) { /* Read how many data sets to process */ int data_num, data_idx; cin >> data_num; /* Process each data set separately */ for(data_idx = 0; data_idx < data_num; data_idx++) { int start = 0; /* The countdown START time */ int total = 0; /* Total of all unconditional hold times */ cond_t ifholds; /* Database of conditional HOLDs */ dataset_t dataset; /* List of all commands in this data set */ /* Read in how many commands this data set contains */ int line_num, line_idx; cin >> line_num; /* Read in all the commands in this data set */ for(line_idx = 0; line_idx < line_num; line_idx++) { cmd_t cmd; /* Read the command time t and the command text */ cin >> cmd.first; getline(cin, cmd.second); /* Add command to dataset */ dataset.push_back(cmd); /* Extract the primary command (START or HOLD) from text line */ istringstream text(cmd.second); string pricmd; text >> pricmd; /* If this is a START command, remember the starting time */ if(pricmd == "START") { start = cmd.first; } } /* Parse each HOLD command in the dataset */ for(dataset_t::iterator i = dataset.begin(); i != dataset.end(); ++i) { /* * Skip START (since we alread handled it) and any HOLDs which * occur at a time t that is larger than the countdown start time * (i.e. these commands would have no effect since they occur * before the countdown clock has started). */ if(i->first >= start) { continue; } /* Skip over the primary command (HOLD) from the text line */ istringstream cmd(i->second); string pricmd; cmd >> pricmd; /* Read the hold time */ int holdtime; cmd >> holdtime; /* Check for the optional "IF" subcommand */ string subcmd; cmd >> subcmd; /* If this is a conditional HOLD; add to condition database */ if(subcmd == "IF") { /* Read name of condition or the "NOT" keyword */ string name; cmd >> name; /* For a "IF NOT" add hold time to "false" condition total */ if(name == "NOT") { cmd >> name; hold_t &hold = ifholds[name]; hold = hold_t(hold.first, hold.second + holdtime); } /* For a "IF" add hold time to "true" condition total */ else { hold_t &hold = ifholds[name]; hold = hold_t(hold.first + holdtime, hold.second); } } /* Otherwise an unconditional HOLD; add hold time to total */ else { total += holdtime; } } /* Find the total minimum and maximum hold times for all conditions */ int mintime = 0, maxtime = 0; for(cond_t::iterator i = ifholds.begin(); i != ifholds.end(); ++i) { hold_t hold = i->second; mintime += min(hold.first, hold.second); maxtime += max(hold.first, hold.second); } /* * The overall minimum and maximum countdown times are equal to the * countdown start time + the total of all unconditional holds + * the total min/max times imposed by all conditional holds */ total += start; cout << total + mintime << " TO " << total + maxtime << endl; } } /* Run program and print out any exceptions that occur */ int main(void) { /* Throw exceptions on failed data extraction in >> operator */ cin.exceptions(ios::failbit); /* Run main body of code */ try { process(); } /* Catch unexpected EOF or bad input data */ catch(ios::failure const &e) { cerr << "Unexpected EOF or data type mismatch on input" << endl; } return 0; }