As I have recently been selected to participate in my country's final preselection to the IOI -- this took me aback -- I have decided to get a bit more serious about competetitive programming.
The Rock-Paper-Scissors Tournament is an old question form the Waterloo Programming Contest 2005-09-17, available on kattis.
What it asks you to do is:
You first get two numbers n and k for the number of participants and the number of games played in the tournament. And then you get k lines detailing every one of those games. Using this data you have to output the winrate for each contestant in three decimal places. A player that has not played a single game throughout the tournament should get a '-' as output.
A zero for the number of players terminates the program.
2 4
1 rock 2 paper
1 scissors 2 paper
1 rock 2 rock
2 rock 1 scissors
2 1
1 rock 2 paper
0
Should give the output
0.333
0.667
0.000
1.000
As far as I know my solution, which follows below, solves this problem perfectly, but, sadly, it is too slow.
My question is, does anyone see where I made a suboptimal choice in the datatype I used or how I calculated a result that causes my program to fail to beat the timelimit? I hope that understanding what I could have done better here allows me to become a better programmer in the future.
#include <iostream>
#include <iomanip>
#include <vector>
#include <unordered_map>
std::unordered_map< std::string, std::unordered_map<std::string, int> >
result(
{
{
"rock",
{
{"rock", 0},
{"paper", -1},
{"scissors", 1}
}
},
{
"paper",
{
{"rock", 1},
{"paper", 0},
{"scissors", -1}
}
},
{
"scissors",
{
{"rock", -1},
{"paper", 1},
{"scissors", 0}
}
}
});
int main() {
int n,
k,
p1,
p2;
std::string m1,
m2;
while (1) {
std::cin >> n;
if (n == 0) {
break;
}
std::cin >> k;
std::vector<int> wins(n, 0);
std::vector<int> losses(n, 0);
while (k--) {
std::cin >> p1;
std::cin >> m1;
std::cin >> p2;
std::cin >> m2;
int v = result[m1][m2];
if (v == 1) {
wins[p1-1]++;
losses[p2-1]++;
} else if (v == -1) {
losses[p1-1]++;
wins[p2-1]++;
}
}
std::cout << std::fixed;
std::cout << std::setprecision(3);
for (int i = 0; i < n; i++) {
float numOfWins = (float)wins[i];
float numOfGames = (float)(wins[i]+losses[i]);
if (numOfGames != 0) {
std::cout << numOfWins/numOfGames << std::endl;
} else {
std::cout << '-' << std::endl;
}
}
std::cout << std::endl;
}
return 0;
}