cppAcademy
FROM LEARNING TO COMPETING

Real problems.
Your next challenge.

Explore the Group C Olympiad and Autumn Tournament archive.
Choose a topic. Find a challenge. Build your solution.

274 tasks: 213 from the Municipal, Regional, and National Olympiad rounds (2009–2026), 57 Autumn Tournament tasks (2007–2025), and 4 previously featured problems. 207 tasks have independently written English summaries, analyses, and C++17 solutions; the remaining entries link to Arena. Difficulty labels are learning estimates, not official ratings. Special formats and source clarifications are explained on affected tasks.
GROUP C2009 · MediumSorting with tie breakers

Formula 1 Season Standings

Autumn Tournament (2009)

Submission name: formula1.cpp

Problem summary

This is an output-only task. Given the supplied 2009 Formula 1 results file, prepare final driver standings. Places 1..8 earn 10,8,6,5,4,3,2,1 points, except Malaysia awards half points. Break equal totals by more wins, then more second places, and so on. Submit the generated output file, not this generator program.

Source clarification. Output-only format: the original judge requires formula1.out, not a program. The fixed input data is available inside https://infos.infosbg.com/files/Contests/ETI/2009/C/problems/formula1.zip . The generator below uses standard input/output for convenient local redirection.

Input

Official data file: 17 blocks, each with a race heading such as Malaysia, 05/04/2009 followed by eight lines such as 1. Jenson Button, Brawn-Mercedes. For the program below redirect that file to standard input.

Output

One line per scoring driver: rank. name: points. Use exactly one space after the period and colon, no empty lines, and print .5 when necessary.

Constraints

The fixed original season contains 17 races and eight scoring places per race. The supplied archive contains the race results and expected standings.

Worked example

Independently prepared two-race teaching example; not the fixed contest answer file.

Input

Australia, 29/03/2009
1. Driver A, Team
2. Driver B, Team
3. Driver C, Team
4. Driver D, Team
5. Driver E, Team
6. Driver F, Team
7. Driver G, Team
8. Driver H, Team
Malaysia, 05/04/2009
1. Driver A, Team
2. Driver B, Team
3. Driver C, Team
4. Driver D, Team
5. Driver E, Team
6. Driver F, Team
7. Driver G, Team
8. Driver H, Team

Output

1. Driver A: 15
2. Driver B: 12
3. Driver C: 9
4. Driver D: 7.5
5. Driver E: 6
6. Driver F: 4.5
7. Driver G: 3
8. Driver H: 1.5

Solution analysis

  1. This task is about preparing an answer file rather than submitting source code. Download the official archive linked in the source clarification, take its Formula-1-Results-2009.in data, and run the generator with input redirection. Save standard output as formula1.out for the output-only judge.
  2. Store doubled points as integers, avoiding floating-point formatting. A normal win adds 20 doubled points; a Malaysia win adds 10. For each driver also count finishes at each of the eight positions. Extract the driver name between the first period and the comma; the team name does not affect standings.
  3. Sort by doubled points descending, then by the entire finish-count array descending. This exactly implements more wins, then more second places, and so on. The fixed official data has no unresolved tie after those criteria; name order is used only as a deterministic fallback for other inputs.
  4. The educational example uses two artificial races with the same top eight drivers. Driver D earns 5+2.5=7.5 points, so doubled storage is 15 and output is 7.5. On the full original season file the first line is 1. Jenson Button: 95, as required by the source.

Why it works

Each race line contributes its position’s prescribed points exactly once. Doubling preserves exact integer and half-point values. A lexicographic descending comparison of finish frequencies implements the stated successive tie breakers. Thus sorting these accumulated records yields the requested standings.

Complexity: O(R·8 + D log D) time and O(D) storage, ignoring bounded name lengths, for R race blocks and D drivers. Tie comparisons inspect eight fixed counters.

Watch out. This program is a generator, not a valid source-code submission to the original output-only task. Do not count team names as drivers or forget Malaysia’s half points. Do not print .0 for integral totals.

Commented C++17 solution

Complete C++17 answer-file generator. Do not submit this source to the original output-only judge.

#include<algorithm>
#include<array>
#include<iostream>
#include<map>
#include<string>
#include<vector>
using namespace std;
struct Driver{
    string name;
    int doubledPoints=0;
    array<int,8>finishes{};
};
int main(){
    array<int,8>points{10,8,6,5,4,3,2,1};
    map<string,Driver>drivers;
    string heading;
    while(getline(cin,heading)){
        if(heading.empty()){
            continue;
        }
        bool halfPoints=heading.find("Malaysia")!=string::npos;
        for(int place=0;place<8;place++){
            string line;
            getline(cin,line);
            size_t period=line.find('.');
            size_t comma=line.find(',',period);
            string name=line.substr(period+2,comma-period-2);
            Driver&driver=drivers[name];
            driver.name=name;
            // Doubled points represent halves exactly with integers.
            driver.doubledPoints+=points[place]*(halfPoints?1:2);
            driver.finishes[place]++;
        }
    }
    vector<Driver>ranking;
    for(const auto&entry:drivers){
        ranking.push_back(entry.second);
    }
    sort(ranking.begin(),ranking.end(),[](const Driver&a,const Driver&b){
        if(a.doubledPoints!=b.doubledPoints){
            return a.doubledPoints>b.doubledPoints;
        }
        if(a.finishes!=b.finishes){
            return a.finishes>b.finishes;
        }
        return a.name<b.name;
    });
    for(size_t i=0;i<ranking.size();i++){
        cout<<i+1<<". "<<ranking[i].name<<": "<<ranking[i].doubledPoints/2;
        if(ranking[i].doubledPoints%2!=0){
            cout<<".5";
        }
        cout<<'\n';
    }
}

Source: Arena Olimpiici ↗