Q:

Preciso de ajuda nessa Questão de programação competitiva

Estou fazendo a questão Pouca Frequência já testei os casos do Udebug porém o juiz online só me retorna Runtime error, pelo o que sei quando isso acontece e quando ele tenta usar posição de memória que não foi alocada, porém eu aloquei mais do que a questão pedia e mesmo assim o problema continua
Meu código 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
double resultado(char *frase);

int main(int argc, char** argv)
{
  int teste, tam, cont, cont2, indice, i;
  char frase[900], presenca[900];
  char *ptr_1, *ptr_2;
  double vetor[900];

 char **nomes = malloc(sizeof(char) * 300);
 char **presencas = malloc(sizeof(char) * 300);

 for(i = 0; i < 300; i++)
 {
     nomes[i] = malloc(sizeof(char) * 900);
 }

 for(i = 0; i < 300; i++)
 {
     presencas[i] = malloc(sizeof(char) * 900);
 }

 scanf("%d", &teste);
 while(teste--)
 {
     cont2 = cont = 0;
     getchar();
     scanf("%d", &tam);
     scanf(" %[^\n]", frase);
     scanf(" %[^\n]", presenca);
     ptr_1 = strtok(frase, " ");

     while(ptr_1 != NULL)
     {
         strcpy(nomes[cont], ptr_1);
         cont++;
         ptr_1 = strtok(NULL, " ");
     }

     ptr_2 = strtok(presenca, " ");
     while(ptr_2 != NULL)
     {
         strcpy(presencas[cont2], ptr_2);
         cont2++;
         ptr_2 = strtok(NULL, " ");
     }

     for(indice = 0; indice < tam ; indice++)
     {
         vetor[indice] = resultado(presencas[indice]);
     }

     for(i = 0; i < tam; i++)
     {
        if(vetor[i] <= 75.0)
        {
            printf("%s ", nomes[i]);
        }
     }
     memset(vetor, 0, sizeof(vetor));
     printf("\n");
}
 for(i = 0; i < 300; i++)
 {
     free(nomes[i]);
 }
 free(nomes);
 for(i = 0; i < 300; i++)
 {
     free(presencas);
 }
  free(presencas);
  return 0;
}

double resultado(char *frase)
{
 int i, tam = strlen(frase);
 double cont = 0;
  for(i = 0; i < tam; i++)
  {
     if(frase[i] == 'M' || frase[i] == 'P')
     {
         cont++;
     }
  }

  return (cont * 100) / tam;
}

A:

#include <stdio.h>
#include <stdlib.h>

/*
  Abaixo, declaro um tipo struct aluno, que contém o nome de um aluno
  e sua frequência.
*/
struct aluno
{
    char nome[51];
    double frequencia;
};

void imprimirreprovados(struct aluno aluno[], int tamanho)
{
    /* count, abaixo, serve para saber se se deve imprimir o espaço
       em branco que intercala cada nome a ser imprimido */
    int count = 0;

    for (int i = 0; i < tamanho; ++i)
    {
        /* como foi dito no enunciado do problema, se a frequencia
           for menor do que 75%, o aluno deve ser enunciado pela
           saida padrao */
        if (aluno[i].frequencia < 0.75)
        {
            if (count > 0)
            {
                printf(" ");
            }
            printf("%s", aluno[i].nome);
            ++count;
        }
    }
    printf("\n");
}

// carrega o vetor de struct aluno's com os nomes. usado na primeira
// linha após a entrada do número de alunos na amostra.
void carregarnomealunos(struct aluno aluno[], int tamanho)
{
    for (int i = 0; i < tamanho; ++i)
    {
        scanf("%s", aluno[i].nome);
    }
}

// carrega a frequência no vetor de struct aluno's. chamada logo
// apos carregarnomealunos(struct aluno[], int).
void carregarfrequenciaalunos(struct aluno aluno[], int tamanho)
{
    /* 'codigo' é o código de letras explicado no enunciado do problema,
       que representa a presença P/ausência A/justificativa de falta M. 
       aproveito o tamanho do vetor para contabilizar o número total de
       aulas, e realizar a conta de porcentagem. */
    char* codigo;

    for (int i = 0; i < tamanho; ++i)
    {
        double totalaulas = 0.0;
        double presencas = 0.0;

        // entrada do codigo na variável 'codigo'.
        scanf("%s", codigo);

        // enquanto não for fim de string (*codigo tem valor 0 no fim da string)
        while (*codigo)
        {
            if (*codigo == 'P')
                presencas += 1.0;
            else if (*codigo == 'M')
                totalaulas -= 1.0;

            totalaulas += 1.0;
            ++codigo;
        }

        // calculo aqui a frequência do caboclo.
        aluno[i].frequencia = totalaulas == 0.0 ? 
            1.0 : presencas / totalaulas;
    }
}

int main(int argc, char* argv[])
{
    int T;

    // entrada do valor T, explicado no enunciado do problema.
    scanf("%d", &T);

    for (int t = 0; t < T; ++t)
    {
        int N;

        // entrada do valor N, explicado no enunciado do problema.
        scanf("%d", &N);

        /* else if (true) abaixo é para separar o joio do trigo;
           quem copiar cegamente o código, vai se ferrar pra
           explicar isto aqui */
        if (true)
        {
             struct aluno alunos[N];
             int tamanho = N;

             carregarnomealunos(alunos, tamanho);
             carregarfrequenciaalunos(alunos, tamanho);
             imprimirreprovados(alunos, tamanho);
        }
    }

    return 0;
}

