Solução Informática - Nível Intermediário - Semana 24

Solução por Anita Ramos

Este é um problema com uma ideia simples, mas que exige uma implementação clara e organizada para que ela funcione. A ideia consiste em ler o nome e todas as doze pontuações de cada jogador, determinando o máximo e o mínimo de cada um para subtrair ao final, e depois organizá-los de acordo com a pontuação (1º determinante) e com os nomes (2º determinante), mantendo sempre a união entre um nome e a sua pontuação a partir de uma struct.

Iniciando a programação então, depois de adicionar a biblioteca, declaramos um vetor inicialmente zerado para armazenar os doze valores de cada pessoa, declaramos uma struct comp com uma char para o nome e uma int para a pontuação e declaramos a função cmp() que tem o formato de bool e compara as pontuações e os nomes de duas pessoas. Essa função primeiro compara as pontuações se elas forem diferentes, retornando verdadeiro ou falso e, depois, se as pontuações são iguais ela compara os nomes por ordem alfabética, a partir da função strcmp() e também retornando verdadeiro ou falso.

Na int main(), temos um loop que funciona enquanto n>0 e em seguida um outro loop para ler todos os nomes e pontuações, em que o nome é lido, as pontuações são lidas e a cada "passagem" nesse loop, as variáveis maxi e mini se atualizam para armazenar o maior e o menor valor, respectivamente. Depois usamos duas vezes a função sort() para garantir uma ordenação correta de acordo com os parâmetros. Por fim, imprimimos o teste em que nos encontramos e iniciamos um loop para imprimir o ranking final, que funciona da seguinte maneira: se i for maior que 0 (exclui-se o primeiro pois ele é a posição 1 e não tem antecessor) e o termo anterior for diferente do atual, posi recebe o valor de i+1, se não ela continua com a mesma posição anterior (este é o caso de empate entre as pontuações). Imprimindo todos as colocações, nomes e pontuações, não podemos esquecer da linha em branco.

Segue o código comentado para melhor compreensão da solução:


#include<bits/stdc++.h> //biblioteca utilizada
using namespace std;
int contador[13]; //declaro o vetor contador
struct comp{ //declaro uma struct de um char e um int
char nome[16];
int pont;
};
bool cmp(comp a, comp b) //bool para comparar
{
if(a.pont!=b.pont)return a.pont>b.pont; //se os valores de pontuação forem diferentes, retorna 'a.pont>b.pont'
else //se não
{
int val=strcmp(a.nome,b.nome); //'val' recebe o resultado da comparação alfabética entre nome 'a' e nome 'b'
if(val<0)return a.nome<b.nome; //se 'val' menor que 0, retorna 'a.nome<b.nome'
else return a.nome>b.nome; //se não, retorna 'a.nome>b.nome'
}
}
int main() {
int n, teste=1; //declaro as variáveis
while(scanf("%d", &n)==1 && n > 0) //enquanto existem casos de teste ('n'>0)
{
comp v[n+1]; //declaro um vetor na forma de struct
for(int i=0; i<n; i++) //loop enquanto 'i'<'n'
{
scanf("%s[^\n]", v[i].nome); //leitura do nome
v[i].pont=0; //zero a pontuacao do vetor na posição 'i'
int maxi=0; //zero a variável 'maxi'
int mini=1010; //maximizo o valor de 'mini'
for(int j=0; j<12; j++) //loop para ler todas as pontuações
{
scanf("%d", &contador[j]); //leitura de cada pontuação
v[i].pont+=contador[j]; //soma-se o valor lido à pontuação da pessoa
maxi=max(maxi,contador[j]); //maxi recebe o máximo entre seu valor antigo e o valor lido
mini=min(mini,contador[j]); //mini recebe o mínimo entre seu valor antigo e o valor lido
}
v[i].pont-=maxi; //subtrai-se o valor máximo lido da pontuação total
v[i].pont-=mini; //subtrai-se o valor mínimo lido da pontuação total
}
sort(v,v+n,cmp); //ordena-se o vetor 'v[]', de acordo com a função 'cmp'
sort(v,v+n,cmp); //ordena-se o vetor 'v[]' novamente, de acordo com a função 'cmp'
printf("Teste %d\n", teste++); //imprimo o teste determinado
int posi=1; //variável 'posi' é declarada, inicialmente valendo 1
for(int i=0; i<n; i++) //enquanto 'i'<'n'
{
if(i>0) //se 'i'>0
{
if(v[i].pont!=v[i-1].pont)posi=i+1; //se a pontuacao anterior é deiferente da atual, soma-se 1 à 'posi'
}
printf("%d %d %s\n", posi, v[i].pont, v[i].nome); //imprime a posição ('posi), a pontução total e o nome
}
printf("\n"); //imprime uma linha em branco
}
return 0; //retorna a 0
}

view raw

obitetri.cpp

hosted with ❤ by GitHub