ALUNO: MATRÍCULA: (Nome Completo em Letra de Imprensa) ASSINATURA: TURMA: Instruções Gerais: 1. A duração da prova é de 1:50h; 2. A tolerância de entrada é de 30 min após o início da prova. Se um aluno terminar a prova em menos de 30min, deverá aguardar em sala antes de entregar a prova e sair de sala; 3. A prova deve ser resolvida apenas nas folhas recebidas e nos espaços reservados para soluções. Não é permitido destacar folhas da prova; 4. A prova é sem consulta a professores, fiscais ou a qualquer tipo de material. A interpretação dos enunciados faz parte da prova; 5. O aluno só poderá realizar a prova e assinar a lista de presença na sua turma/sala; 6. O aluno só poderá manter junto a si: lápis, borracha e caneta. Caso necessário, o fiscal poderá solicitar ajuda a outro aluno e apenas o fiscal repassará o material emprestado. Instruções Específicas: 1. Esta prova possui 4 folhas, contando com a capa. Confira; 2. As questões devem ser resolvidas usando a linguagem de programação C; 3. A prova deve ser feita preferencialmente à lápis. O aluno deve usar a caneta apenas para preencher o cabeçalho da prova (nome, matrícula, turma) e assinar a lista de presença; 4. Todo papel diferente do distribuído pelo fiscal (independentemente do conteúdo) e/ou qualquer dispositivo eletrônico (celular, tablet, etc) ligado ou não encontrado visível junto ao aluno implicará no recolhimento imediato da prova e a atribuição de nota zero à mesma; 5. Caso o aluno tenha perguntas ou observações a serem feitas ao professor, deverá descrevê-las na folha de rosto, na área reservada para observações stdio.h: int scanf (char* formato,...); int printf (char* formato,...); FILE* fopen (char* nome, char* modo); int fclose (FILE* fp); int fscanf (FILE* fp, char* formato,...); int fprintf (FILE* fp, char* formato,...); char*fgets(char* str, int size, FILE* fp); int sscanf(char* str, char* formato,...); stdlib.h: void* malloc (int nbytes); void free (void* p); Valor Nota (90% G2) Revisão Q1A 0.5 Q1B 2.5 Q2 2.5 Q3A 2.5 Q3B 2.0 Total 10.0 Algumas Funções de Bibliotecas ( NESTA PROVA VOCE PODE USÁ-LAS EM QUALQUER QUESTÃO ) math.h: double sqrt (double x); double pow (double x, double exp); double cos (double radianos); double sin (double radianos); string.h: int strlen (char* s); int strcmp (char* s, char *t); char* strcpy (char* destino, char* fonte); char* strncpy (char* destino, char* fonte, int n); char* strcat (char* destino, char* fonte); char* strdup (char* s); void qsort (void *v, int n, int tam, int (*cmp)(const void*, const void*)); void * bsearch(void * info, void * v, int n, int tam, int (*cmp)(const void *, const void *)); Espaço reservado para observações do aluno e futuros pedidos de revisão: 1
1ª Questão Considere um vetor de ponteiros para o tipo estruturado Voo, com os vôos que partem de um aeroporto em um determinado dia. typedef struct horario Horario; struct horario typedef struct voo Voo; struct voo int hora; char nomevoo[8]; int minuto; Horario partida; ; char destino[21]; 1.A (0,5 ponto) Escreva a função int horário (Horario a, Horario b) que compara dois horários dados e retorna um número positivo, caso a seja um horário maior que b; um número negativo, caso a seja menor que b ou 0 (zero) se a e b forem iguais. Por exemplo, se a for 15:30 e b for 15:40, então a função retorna um valor negativo. Solução int horario(horario a, Horario b) int ma = 60*a.hora + a.minuto; int mb = 60*b.hora + b.minuto; return ma-mb; 1.B (2,5 pontos) Escreva a função quickvoos, que: recebe um vetor de ponteiros para Voo e o número total de vôos; ordena o vetor crescentemente por horário de partida. Para um mesmo horário de partida, os vôos devem ficar ordenados alfabeticamente por nomevoo. A sua função deve implementar o método de ordenação rápida (quick sort) e deve usar uma função auxiliar de comparação, chamada comparavoos, para comparar 2 vôos de acordo com o critério descrito acima. Se quiser, você pode usar a função qsort da biblioteca. Mesmo que você não tenha resolvido o item 1.A, a função horario poderá ser utilizada neste item. Exemplo: Fig.1 2
Solução 1: static int comparavoos(voo * a, Voo * b) int cmph = horario(a->partida,b->partida); int cmpn = strcmp(a->nomevoo,b->nomevoo); return cmph>0 (cmph==0 && cmpn>0); void quickvoos(voo ** v, int n) // Quick Sort Voo * x = v[0]; Voo * temp; int a = 1; int b = n-1; if (n<=1) return; do while (a < n &&!comparavoos(v[a],x)) a++; while (comparavoos(v[b],x)) b--; if (a < b) temp = v[a]; v[a] = v[b]; v[b] = temp; a++; b--; while (a <= b); v[0] = v[b]; v[b] = x; quickvoos(v,b); quickvoos(&v[a],n-a); Solução 2: static int comparavoos(const void *a, const void *b) Voo **aa = (Voo**)a; Voo **bb = (Voo**)b; int cmph = horario((*aa)->partida, (*bb)->partida); int cmpn = strcmp((*aa)->nomevoo, (*bb)->nomevoo); return cmph>0 (cmph==0 && cmpn>0); void quickvoos(voo ** v, int n) qsort(v, n, sizeof(voo*), comparavoos); 3
2ª Questão (2,5 pontos) Considere que uma loja guarda os códigos numéricos e alfanuméricos de seus produtos em uma lista encadeada do tipo estruturado No: typedef struct informacao Informacao; typedef struct no No; struct informacao struct no int codigo; Informacao *info; char nome[31]; No *prox; ; ; Escreva a função quebraaomeio que quebra esta lista encadeada do tipo estruturado No em duas sublistas e retorna o endereço do primeiro nó da segunda metade da lista original. Se o número total de elementos da lista original é ímpar, o elemento extra fica na primeira metade. Se este número é menor que 2, a lista retornada é vazia. Fig. 2 Fig. 2 Solução 4
Solução No *quebraaomeio(no *lst) No *p1, *p2; int cont; if(lst == NULL lst->prox == NULL) return NULL; cont = 0; for (p1=lst; p1!= NULL; p1= p1->prox) cont++; cont++; p1 = lst; for (cont = cont/2; cont>1; cont--) p1= p1->prox; p2= p1->prox; p1->prox= NULL; return p2; 5
3ª Questão Considere uma clínica com várias especialidades médicas, onde uma especialidade é definida pelo tipo estruturado Especialidade, que contém o nome da especialidade e uma lista encadeada representando os dados de cada médico desta especialidade: typedef struct medico Medico; struct medico char nomedomed[51]; /* nome do medico */ float valordaconsulta; /* valor da consulta com esse medico */ Medico *prox; /* ponteiro para o próximo médico da lista */ ; typedef struct especialidade Especialidade; struct especialidade char nomeesp [21]; /*nome da especialidade */ Medico *lstmedicos; /* ponteiro para o primeiro nó de uma lista simplesmente encadeada de médicos dessa especialidade */ ; Considere agora a existência de um vetor de Especialidade, já ordenado alfabeticamente pelo nome da especialidade (nomeesp) (Fig.3). 3.A (2,5 pontos) Escreva a função buscaespec que faz uma busca binária no vetor de especialidades por um nome de uma dada especialidade e retorna o índice dessa especialidade, se encontrar, ou retorna -1 se não encontrar. Por exemplo, para a especialidade otorrino na Fig. 3, a função retorna o índice 4. Use obrigatoriamente uma função auxiliar de comparação. 3.B (2,0 pontos) Usando obrigatoriamente a função buscaespec da questão anterior (mesmo que você não a tenha definido) escreva a função MedicoNaEspecialidade que: - recebe 4 parâmetros: um vetor de Especialidade ordenado alfabeticamente por nome, o número total de especialidades, o nome de uma especialidade e o nome de um médico, e - retorna o endereço da estrutura Medico que contém o médico procurado naquela especialidade ou retorna NULL se a especialidade ou o médico em questão não são encontrados. No exemplo da Fig. 3, para nome da especialidade otorrino e nome do médico ana, a função retorna o ponteiro para a estrutura indicada pela caixa sombreada. alergia dermato endocrino gastro otorrino pneumo edu 100 eli rui vik lia dina bia liz tati leo teo val caio ana mac cris Fig. 3 Os valores de valordaconsulta não estão indicados ao lado de cada nome de médico para simplificar a figura. 6
3.A Solução 1: static int compespec(char * a, Especialidade b) return strcmp(a,b.nomeesp); int buscaespec(int n, Especialidade * v, char * nomeespec) int ini=0; int fim=n-1; int meio, cmp; while (ini <= fim) meio=(ini+fim)/2; cmp=compespec(nomeespec,v[meio]); if (cmp<0) fim=meio-1; else if (cmp>0) ini=meio+1; else return meio; return -1; 3.A Solução 2: static int compespec(const void* a, const void* b) char *info = (char*)a; Especialidade *bb = (Especialidade*)b; return strcmp(info, bb->nomeesp); int buscaespec(int n, Especialidade * v, char *nomeespec) Especialidade *p; p = (Especialidade*)bsearch(nomeEspec, v, 6, sizeof(especialidade), compespec); if (p!= NULL) return p - v; return -1; 7
3.B Solução: Medico * buscamedico(medico * lst, char * nomemed) Medico * p; for (p=lst; p!= NULL; p=p->prox) if(strcmp(nomemed,p->nomedomed)==0) return p; return NULL; Medico * MedicoNaEspecialidade (Especialidade * v, int n, char * nomeesp, char * nomemed) int pos; pos = buscaespec(n,v,nomeesp); // busca binaria if (pos>=0) return buscamedico(v[pos].lstmedicos, nomemed); else return NULL; 8