p400.ans1
======================
2 4
1 2

=================
p400.cpp
======================
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

struct TeamInfo {
    string name;
    int solved;
    int64_t penalty;
    int rank;
    vector<int> rejects_unsolved;
};

int n_problems;
vector<TeamInfo> teams;
int balloons;
string my_team;

bool read_nonempty_line(string& line) {
    while(getline(cin, line)) {
        for(char c: line) {
            if(!isspace((unsigned char)c)) {
                return true;
            }
        }
    }
    return false;
}

bool is_team_row(const string& line) {
    for(char c: line) {
        if(c == '.' || c == '+' || c == '-') {
            return true;
        }
    }
    return false;
}

TeamInfo parse_team_row(const string& line) {
    TeamInfo t;
    int last = (int)line.size() - 1;
    while(last >= 0 && isspace((unsigned char)line[last])) {
        last--;
    }
    auto skip_spaces = [&]() {
        while(last >= 0 && line[last] == ' ') {
            last--;
        }
    };
    auto read_digits_back = [&]() {
        int64_t val = 0, base = 1;
        while(last >= 0 && isdigit((unsigned char)line[last])) {
            val += base * (line[last] - '0');
            base *= 10;
            last--;
        }
        return val;
    };
    for(int p = 0; p < n_problems; p++) {
        skip_spaces();
        int64_t num = read_digits_back();
        skip_spaces();
        char sign = line[last--];
        if(sign != '+') {
            t.rejects_unsolved.push_back((int)num);
        }
    }
    skip_spaces();
    t.penalty = read_digits_back();
    skip_spaces();
    t.solved = (int)read_digits_back();

    int s = 0;
    while(s < (int)line.size() && line[s] == ' ') {
        s++;
    }
    int rank = 0;
    while(s < (int)line.size() && isdigit((unsigned char)line[s])) {
        rank = rank * 10 + (line[s] - '0');
        s++;
    }
    while(s < (int)line.size() && line[s] == ' ') {
        s++;
    }
    while(last >= s && line[last] == ' ') {
        last--;
    }
    t.rank = rank;
    t.name = line.substr(s, last - s + 1);
    return t;
}

bool read() {
    string line;
    if(!read_nonempty_line(line)) {
        return false;
    }
    {
        istringstream iss(line);
        string tok;
        iss >> tok >> tok >> tok >> tok;
        n_problems = 0;
        while(iss >> tok) {
            n_problems++;
        }
    }
    teams.clear();
    while(true) {
        if(!read_nonempty_line(line)) {
            return false;
        }
        if(!is_team_row(line)) {
            balloons = stoi(line);
            break;
        }
        teams.push_back(parse_team_row(line));
    }
    if(!read_nonempty_line(line)) {
        return false;
    }
    int s = 0;
    while(s < (int)line.size() && isspace((unsigned char)line[s])) {
        s++;
    }
    int e = (int)line.size();
    while(e > s && isspace((unsigned char)line[e - 1])) {
        e--;
    }
    my_team = line.substr(s, e - s);
    return true;
}

bool better_than(const TeamInfo& a, const TeamInfo& b) {
    if(a.solved != b.solved) {
        return a.solved > b.solved;
    }
    return a.penalty < b.penalty;
}

void accept_one(TeamInfo& t) {
    auto it = min_element(t.rejects_unsolved.begin(), t.rejects_unsolved.end());
    t.solved++;
    t.penalty += 241 + 20 * (int64_t)(*it);
    t.rejects_unsolved.erase(it);
}

int high_pos(vector<TeamInfo> ts, int my_idx, int balloons_left) {
    TeamInfo& me = ts[my_idx];
    while(balloons_left > 0 && !me.rejects_unsolved.empty()) {
        accept_one(me);
        balloons_left--;
    }
    int n = (int)ts.size();
    bool absorbed_elsewhere;
    if(my_idx != n - 1) {
        absorbed_elsewhere = true;
    } else if(my_idx == 0) {
        absorbed_elsewhere = true;
    } else {
        absorbed_elsewhere = ts[my_idx - 1].solved < n_problems;
    }
    if(absorbed_elsewhere) {
        balloons_left = 0;
    }
    if(balloons_left > 0) {
        me.penalty += 20 * (int64_t)balloons_left;
    }
    int rank = my_idx + 1;
    for(int i = my_idx - 1; i >= 0 && !better_than(ts[i], me); i--) {
        rank--;
    }
    return rank;
}

int low_pos(vector<TeamInfo> ts, int my_idx, int balloons_left) {
    int n = (int)ts.size();
    for(int i = my_idx - 1; i >= 0 && ts[i].rank == ts[my_idx].rank; i--) {
        if(i == 0 || ts[i - 1].rank != ts[my_idx].rank) {
            swap(ts[i], ts[my_idx]);
            my_idx = i;
            break;
        }
    }
    TeamInfo& me = ts[my_idx];
    int rank = me.rank;
    int i = my_idx + 1;
    while(balloons_left > 0 && i < n) {
        int j = i;
        while(i < n && ts[i].solved == ts[j].solved) {
            i++;
        }
        int det = me.solved - ts[j].solved;
        if(balloons_left < det) {
            break;
        }
        for(int l = j; l < i; l++) {
            for(int k = 0; k < det; k++) {
                accept_one(ts[l]);
            }
        }
        for(int l = j; balloons_left >= det && l < i; l++) {
            if(better_than(ts[l], me)) {
                balloons_left -= det;
                rank++;
            }
        }
        for(int l = j; balloons_left >= det + 1 && l < i; l++) {
            if(!better_than(ts[l], me) && !ts[l].rejects_unsolved.empty()) {
                balloons_left -= (det + 1);
                accept_one(ts[l]);
                rank++;
            }
        }
    }
    return rank;
}

void solve() {
    // This is purely an implementation problem: a careful parser plus a
    // greedy simulation, no clever algorithmic trick.
    //
    // Best (smallest) place: our team takes as many of its unsolved problems
    // as possible at minute 241, choosing the unsolved problem with the
    // fewest existing rejects first to minimize the added penalty. Any
    // leftover balloons are assumed absorbed by other teams without changing
    // our rank. The only case where they cannot be absorbed elsewhere is
    // when we are last AND every team above us has already solved every
    // problem: then each leftover balloon is forced onto our team as an
    // extra reject (+20 penalty). Once our state is fixed, the rank is
    // 1 + (# teams originally above us that still beat the new state). The
    // standings are sorted, so we scan upward from our position and stop at
    // the first beater.
    //
    // Worst (largest) place: keep our team's state untouched and try to push
    // as many of the teams currently below us past us. We first move our
    // team to the head of its rank-tie block so that tied teams below can
    // be made into overtakes through the +1-accept path. Then walk the
    // table in groups of equal solved count. A team in a group with
    // det = my_solved - their_solved fewer accepts overtakes us with either
    // det accepts (tied solved, win on penalty) or det + 1 accepts (strictly
    // out-solving us). Within each group we greedily count teams that
    // overtake at cost det, then teams that overtake at cost det + 1, until
    // balloons run out or no more groups are reachable. Each overtake adds
    // one to the rank.

    int my_idx = -1;
    for(int i = 0; i < (int)teams.size(); i++) {
        if(teams[i].name == my_team) {
            my_idx = i;
            break;
        }
    }
    int hp = high_pos(teams, my_idx, balloons);
    int lp = low_pos(teams, my_idx, balloons);
    cout << hp << ' ' << lp << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    while(read()) {
        solve();
    }

    return 0;
}

=================
p400.in1
======================
Rank Team = Penalty X Y
1 Tarasov SU 3 2 33 + +
2 IMHO 1 1 20 + -1
3 Mozgow SU x 33 1 30. +
3 MiTV 1 30 + -3
5 Opel SU 0 0..
2
MiTV
Rank Team = Penalty A
1 aa 0 0 -1
1 ba 0 0 -8
2
ba

=================
statement.txt
======================
400. The last hour of the contest
Time limit per test: 0.25 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



It's your lucky day - your team took part in the world finals programming contest. The competition has just finished and all competitors are looking forward to the results. Of course your team is not an exception.

According to the rules of the competition, duration of the contest is 5 hours and team standings are frozen during the last hour of the contest — from 241st to 300th minute. Due to this reason the actual results are unknown to the participants and are only announced at the awards ceremony. It is a long-term tradition though, to get a balloon at the world finals for every problem solved. This information can sometimes be of use during the competition.

While waiting for the awards ceremony, your team decided to evaluate chances to win and determine the place which it can take in the final standings. Here is the information that you have:



Standings table at the end of the 240th minute

Total amount of balloons given to all teams within the last hour

Exact rules of the competition



To solve this problem you should mind the following contest rules:



The competition lasts for 300 minutes, minutes are numbered from 1 to the 300.

Position of a team is defined by the amount of the problems solved and penalty time.

The more problems are solved the higher place a team gets. If two or more teams have the same amount of problems solved, the sorting is done by the penalty time in ascending order (less penalty time — higher place). If two or more teams have the same amount of problems solved and the same penalty time, they share the same place. Rank of a team equals the number of teams performing better + 1. If there are no other teams performing better, the team takes the 1st place.

Total penalty time is the sum of the penalty times consumed for each problem solved. The time consumed for a solved problem is the number of a minute (i. e. an integer between 1 and 300) when the correct submission was made plus 20 penalty minutes for every previously rejected run for that problem. There is no penalty time for a problem that is not solved.

When solution for a particular problem is accepted, a team is not allowed to submit solutions of the same problem anymore.



Frozen standings are given to you in a text form and look as follows:



The first line consists of "", "", "", and "" tokens followed by a list of problems identifiers. Every problem identifier is a capital Latin letter 'A'-'Z'. All problem identifiers are different.

The second and the subsequent lines contain team standings itself. These lines are given to you. in non-descending order of team rank

Every line contains a place of a team, a name of a team, the amount of problems solved and the result for every problem.

Every result on a problem is



character "", if the team didn't submit the problem;
"", if the problem was not accepted and the team made x unsuccessful submits;

"", if the problem was accepted and the team made x unsuccessful submits before the accepted run; x is always omitted if it equals to 0.





You are given the frozen standings, and your task is to calculate the minimum and the maximum place your team can get after the contest is over.

Input
Input file contains one or more set of input data.

First lines of each set contain the standings table at the end of the 240th minute in the format described above. In each line the tokens are split with at least one whitespace character. The next line contains the amount of balloons given to all teams within the last hour of the contest (from 241st to 300th minutes). The last line of the set is the name of your team. All team names consist of Latin letters 'A'-'Z', 'a'-'z', numbers and whitespaces. Each team name contains no more than 100 characters, doesn't start/end with a whitespace, and contains not less then 1 non-whitespace character. All team names are unique within a single set of input data. The number of teams is between 1 and 100. The number of problems is between 1 and 26. The total number of rejected attempts in frozen standings table is not more than 1000, but the total number of rejected attempts in final standings is unlimited. The number of balloons is non-negative.

You may assume that the size of the input file is not more than 100 KB.

Output
For every input data set, please print two integer numbers in the line — the minimum and the maximum place your team can get after the contest is over.

Example(s)
sample input
sample output
Rank Team = Penalty X Y
1 Tarasov SU 3 2 33 + +
2 IMHO 1 1 20 + -1
3 Mozgow SU x 33 1 30. +
3 MiTV 1 30 + -3
5 Opel SU 0 0..
2
MiTV
Rank Team = Penalty A
1 aa 0 0 -1
1 ba 0 0 -8
2
ba

=================
