Solução Fórmula 1

Solução de Roger Benet, comentários de Rogério Júnior

Clique aqui para ver o problema original.

Vamos criar uma struct de nome piloto para representarmos cada um dos pilotos.Ela guardará dois inteiros: pontos e id que deverão representar quantos pontos o piloto fez em um determinado sistema e seu número de identificação, respectivamente. Além disso, ela também guardará um vetor de 100 inteiros de nome pos, que guardará, na posição i, quantas vezes o piloto foi o i-ésimo colocado.

Agora, vamos declarar um vetor de piloto de nome vet, onde vet[i] representa o piloto de identificação i. Primeiramente, percorreremos este vetor, atribuindo o valor correto de identificação ao elemento id de cada posição e zerando os valores de pontos e pos.

Para cada corrida, se o piloto j ficou na posição x, aumentaremos o valor de vet[j].pos[x] em uma unidade. Agora, para cada sistema de pontuação, atribuiremos o número de pontos feito pelo piloto i ao elemento pontos da posição i de vet, da seguinte forma: para cada posição i que dá pontos a um piloto, veremos quantos pontos ela ganha no sistema em que estamos olhando, chamaremos esse valor de x e, para cada piloto j, adicionaremos a seus pontos (salvos no elemento pontos de vet[j])  a quantidade de vezes que ele ficou na posição i (salva no elemento pos[i] de vet[j]) multiplicada pelos x pontos que essa posição dá.

Após atribuirmos a posição correta para cada piloto, basta ordenarmos o vetor vet usando uma função que ordene pela maior quantidade de pontos, usando o menor índice como critério de desempate. Feito isso, imprimimos o identificador do piloto na primeira posição do vetor ordenado (vet[1].id, se indexarmos de 1 a p) e de todos os outros, a partir da segunda posição, que têm pontuação igual à do primeiro, sempre com um espaço em branco antes do número. Feito isso, basta imprimir uma quebra de linha, zerarmos as pontuações de todos os pilotos e analisarmos o próximo sistema de pontuações. Segue o código comentado para melhor entendimento:


#include <cstdio> // scanf e printf
#include <algorithm> // sort
#include <cstring> // memset
using namespace std;
// struct que representa um piloto
struct piloto {
int pontos, id, pos[110];
};
// função que compara pilotos
bool cmp (piloto a, piloto b){
// ela dá prioridade à maior pontuação
if(a.pontos > b.pontos) return true;
if(a.pontos < b.pontos) return false;
// e usa o menor valor de id como desempate
return a.id < b.id;
}
// declaro as variáveis que vou usar
int g, p, s, k;
piloto vet[110];
int main(){
// para cada caso dado na entrada
while(scanf("%d %d", &g, &p) and g != 0){
// para cada piloto
for(int i = 1; i <= p; i++){
// atribuo o valor inicial correto a cada elemento seu
vet[i].id = i;
vet[i].pontos = 0;
memset(vet[i].pos, 0, sizeof vet[i].pos);
}
// para cada GP
for(int i = 0; i < g; i++)
// olho a posição de cada piloto
for(int j = 1; j <= p; j++){
// salvo-a em x
int x;
scanf("%d", &x);
// e aumento, em vet[j], o número de vezes
// que o piloto j chegou na posição x
vet[j].pos[x]++;
}
// leio o número de sistemas de pontuação
scanf("%d", &s);
// e analiso cada sistema
while(s--){
// leio quantas posições valem pontos
scanf("%d", &k);
// e para cada posição i que vale ponto
for(int i = 1; i <= k; i++){
// salvo em x quantos ponto ela vale
int x;
scanf("%d", &x);
// e adiciono no elemento pontos de cada piloto
// os pontos que ele ganhou por cada vez que chegou na posição i
for(int j = 1; j <= p; j++) vet[j].pontos += vet[j].pos[i] * x;
}
// ordeno o vetor de pilotos
sort(vet+1, vet+1+p, cmp);
// imprimo o id do primeiro piloto
printf("%d",vet[1].id);
// e de todos os seguintes que têm a mesa pontuação do primeiro
int x = 2;
while(vet[x].pontos == vet[1].pontos){
printf(" %d",vet[x].id);
x++;
}
// imprimo a quebra de linha
printf("\n");
// e zero os pontos de cada piloto
// para analisar o próximo sistema
for(int i = 1; i <= p; i++) vet[i].pontos = 0;
}
}
return 0;
}

view raw

formula1.cpp

hosted with ❤ by GitHub