Advertisement
Guest User

Untitled

a guest
Nov 25th, 2015
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.70 KB | None | 0 0
  1. /*
  2.  
  3. # Trabalho
  4.  
  5. Este programa contém uma implementação parcial de um heap mínimo, contendo o
  6. necessário para resolver o problema "Telemarketing" da Olimpíada Brasileira de
  7. Informática de 2007. A descrição do problema se encontra em
  8. http://olimpiada.ic.unicamp.br/pratique/programacao/nivel1/2007f2p1_tele. Leia
  9. a descrição para entender o que significa Vendedor e como se determina quando
  10. um vendedor é menor do que outro.
  11.  
  12. Algumas funções contém um comentário "// TODO". Essas funções estão
  13. incompletas. Seu trabalho é escrever o código dessas funções incompletas, sem
  14. no entanto modificar nada mais no programa. O programa é autotestável: a
  15. função main chama as funções e compara a saída obtida com a saída esperada.
  16. Ao final, ele imprime sua nota, entre 0 e 40.
  17.  
  18. Além da correção automática, o código-fonte será lido para determinar se a
  19. função realmente faz o que deveria ou se responde corretamente apenas às
  20. entradas que são testadas.
  21.  
  22. O trabalho deve ser feito em equipes de 1, 2 ou 3 alunos. Cada aluno só pode
  23. participar de um equipe.
  24.  
  25. # Entrega
  26.  
  27. A solução deve ser enviada para o e-mail <rodrigo@dcc.ufba.br> até as 23:59:59
  28. do sábado, dia 28 de novembro de 2015 (horário local de Salvador). O e-mail
  29. deve ter o assunto "[MATA40] Trabalho sobre Heaps" e deve conter como anexo um
  30. único arquivo que representa o código-fonte da solução na linguagem C. O nome
  31. do arquivo deve consistir apenas dos números de matrícula dos alunos da equipe,
  32. separados por hífens, e da extensão .c. Exemplo: 200310593-210115051.c.
  33.  
  34. */
  35.  
  36.  
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <stdarg.h>
  41.  
  42. /////////////////////////////////////////////////////////////////////
  43. // Definição dos structs.
  44. /////////////////////////////////////////////////////////////////////
  45.  
  46. typedef struct {
  47. // Identificador do vendedor. Número sequencial a partir de 1.
  48. int id;
  49. // Instante em que o vendedor estará disponível.
  50. int tempo;
  51. } Vendedor;
  52.  
  53. typedef struct {
  54. int tamanho;
  55. Vendedor *itens;
  56. } Heap;
  57.  
  58. /////////////////////////////////////////////////////////////////////
  59. // Funções de heap.
  60. /////////////////////////////////////////////////////////////////////
  61.  
  62. /**
  63. * Retorna o índice do filho à esquerda do item no índice pos.
  64. * Ex.: indiceFilhoEsq(3) retorna 7.
  65. */
  66. int indiceFilhoEsq(int pos) {
  67. return (2*pos)+1;
  68. }
  69.  
  70. /**
  71. * Retorna o índice do filho à direita do item no índice pos.
  72. * Ex.: indiceFilhoEsq(3) retorna 8.
  73. */
  74. int indiceFilhoDir(int pos) {
  75. return (2*pos)+2;
  76. }
  77.  
  78. /**
  79. * Retorna 1 se o item na posição pos1 do heap for menor do que
  80. * o item na posição pos2 do heap.
  81. * Caso contrário, retorna 0.
  82. */
  83. int menor(Heap *heap, int pos1, int pos2) {
  84. if(heap->itens[pos1-1].id < heap->itens[pos2-1].id){
  85. return 1;
  86. }
  87. return 0;
  88. }
  89.  
  90. /**
  91. * Cria um vetor que representa um heap mínimo no qual cada item é um Vendedor.
  92. * O item na posição i do vetor deve ter id = (i + 1) e tempo = 0.
  93. */
  94. Heap *criaHeapMin(int tamanho) {
  95. Heap *heap = malloc(sizeof(Heap));
  96. heap->tamanho = tamanho;
  97. heap->itens = malloc(tamanho * sizeof(Vendedor));
  98.  
  99. for (int i = 0; i < tamanho; i++) {
  100. heap->itens[i].id = i + 1;
  101. heap->itens[i].tempo = 0;
  102. }
  103.  
  104. return heap;
  105. }
  106.  
  107. /**
  108. * Destrói o heap.
  109. */
  110. void destroiHeap(Heap *heap) {
  111. free(heap->itens);
  112. free(heap);
  113. }
  114.  
  115. Vendedor *criaVendedor(int id, int tempo) {
  116. Vendedor *vendedor = malloc(sizeof(Vendedor));
  117. vendedor->id = id;
  118. vendedor->tempo = tempo;
  119. return vendedor;
  120. }
  121.  
  122. /**
  123. * Retorna o índice do último item que não é folha.
  124. */
  125. int indiceUltimoNaoFolha(Heap *heap) {
  126. return (heap->tamanho - 2) / 2;
  127. }
  128.  
  129. /**
  130. * Retorna 1 se o heap é um heap mínimo; caso contrário, retorna 0.
  131. */
  132. int ehHeapMin(Heap *heap) {
  133. //varremos de N ate o tamanho do heap-1
  134. for(int n=0; n < heap->tamanho-1; n++){
  135. //Verificamos se o tempo do item do Pai e maior do que o do filho
  136. if(heap->itens[n].tempo > heap->itens[n+1].tempo){
  137. return 0;
  138. }else{
  139. if(heap->itens[n].tempo == heap->itens[n+1].tempo){
  140. if(heap->itens[n].id > heap->itens[n+1].id){
  141. return 0;
  142. }
  143. }
  144. }
  145. }
  146. return 1;
  147. }
  148.  
  149. /**
  150. * Retorna 1 se o item na posição 1 é uma folha.
  151. */
  152. int ehFolha(Heap *heap, int pos) {
  153. int n = heap->tamanho;
  154. return pos >= n/2 && pos < n;
  155. }
  156.  
  157. /**
  158. * Troca dois itens de posição.
  159. */
  160. void troca(Vendedor *a, Vendedor *b) {
  161. Vendedor temp = *a;
  162. *a = *b;
  163. *b = temp;
  164. }
  165.  
  166.  
  167. /**
  168. * Afunda um elemento no heap.
  169. */
  170.  
  171.  
  172. void afunda(Heap *heap, int pos) {
  173. int i,a;
  174. if (pos % 2 == 0){
  175. if(heap->itens[pos].tempo > heap->itens[pos/2].tempo){
  176. i = heap->itens[pos/2].tempo;
  177. heap->itens[pos/2].tempo = heap->itens[pos].tempo;
  178. heap->itens[pos].tempo = i;
  179. a = pos/2;
  180. }
  181. if(ehHeapMin(heap) == 0){
  182. afunda(heap, a);
  183. }
  184. }
  185. if( pos % 2 == 1){
  186. if(heap->itens[pos].tempo > heap->itens[(pos-1)/2].tempo){
  187. i = heap->itens[(pos-1)/2].tempo;
  188. heap->itens[(pos-1)/2].tempo = heap->itens[pos].tempo;
  189. heap->itens[pos].tempo = i;
  190. a = (pos-1)/2;
  191. }
  192. if(ehHeapMin(heap) == 0){
  193. afunda(heap, a);
  194. }
  195. }
  196. }
  197.  
  198. /////////////////////////////////////////////////////////////////////
  199. // Funções auxiliares
  200. /////////////////////////////////////////////////////////////////////
  201.  
  202. void imprimeVendedor(Vendedor *v) {
  203. printf("(%d %ds) ", v->id, v->tempo);
  204. }
  205.  
  206. void imprimeHeap(Heap *heap) {
  207. for (int i = 0; i < heap->tamanho; i++) {
  208. imprimeVendedor(&heap->itens[i]);
  209. }
  210. printf("-\n");
  211. }
  212.  
  213. /////////////////////////////////////////////////////////////////////
  214. // Funções relacionadas ao problema de telemarketing.
  215. /////////////////////////////////////////////////////////////////////
  216.  
  217. Heap *inicializaProblemaHeap(int numVendedores) {
  218. return criaHeapMin(numVendedores);
  219. }
  220.  
  221. int *inicializaProblemaVendas(int numVendedores) {
  222. int *vendas = malloc(numVendedores * sizeof(int));
  223. for (int i = 0; i < numVendedores; i++) {
  224. vendas[i] = 0;
  225. }
  226. return vendas;
  227. }
  228.  
  229. void fazChamada(Heap *heap, int *vendas, int tempo) {
  230. vendas[heap->itens[0].id - 1] += 1;
  231. heap->itens[0].tempo += tempo;
  232. afunda(heap, 0);
  233. }
  234.  
  235. /////////////////////////////////////////////////////////////////////
  236. // Funções usadas para facilitar a correção das outras funções.
  237. /////////////////////////////////////////////////////////////////////
  238.  
  239. int total = 0;
  240. void corrige(int pontuacao, int acertou) {
  241. if (!acertou) {
  242. pontuacao = 0;
  243. }
  244. printf("%d ", pontuacao);
  245. total += pontuacao;
  246. }
  247.  
  248. void preencheHeap(Heap *heap, int tamanho, ...) {
  249. va_list varg;
  250. tamanho = heap->tamanho;
  251. va_start(varg, tamanho);
  252.  
  253. for (int i = 0; i < heap->tamanho; i++) {
  254. heap->itens[i].id = va_arg(varg, int);
  255. heap->itens[i].tempo = va_arg(varg, int);
  256. }
  257. }
  258.  
  259. int comparaHeap(Heap *heap, int tamanho, ...) {
  260. va_list varg;
  261. tamanho = heap->tamanho;
  262. va_start(varg, tamanho);
  263.  
  264. for (int i = 0; i < heap->tamanho; i++) {
  265. if (va_arg(varg, int) != heap->itens[i].id)
  266. return 0;
  267. if (va_arg(varg, int) != heap->itens[i].tempo)
  268. return 0;
  269. }
  270.  
  271. return 1;
  272. }
  273.  
  274. int comparaVetorInt(int *vetor, int tamanho, ...) {
  275. va_list varg;
  276. va_start(varg, tamanho);
  277.  
  278. for (int i = 0; i < tamanho; i++) {
  279. if (va_arg(varg, int) != vetor[i])
  280. return 0;
  281. }
  282.  
  283. return 1;
  284. }
  285.  
  286. void imprimeVetor(int *vetor, int tamanho) {
  287. for (int i = 0; i < tamanho; i++) {
  288. printf("%d ", vetor[i]);
  289. }
  290. printf("\n");
  291. }
  292.  
  293. ///////////////////////////////////////////////////////////////////
  294. // NAO REMOVA ESTA LINHA. ABAIXO DESTA LINHA SO PODE TER O main().
  295. ///////////////////////////////////////////////////////////////////
  296.  
  297. int main(int argc, char *argv[]) {
  298.  
  299. /////////////
  300. // 3
  301.  
  302. corrige(1, indiceFilhoEsq(0) == 1);
  303. corrige(1, indiceFilhoEsq(5) == 11);
  304. corrige(1, indiceFilhoDir(5) == 12);
  305.  
  306. Heap *heap = criaHeapMin(3);
  307. heap->itens[0] = *criaVendedor(1, 4);
  308. heap->itens[1] = *criaVendedor(2, 4);
  309. heap->itens[2] = *criaVendedor(3, 5);
  310.  
  311. /////////////
  312. // 7
  313.  
  314. corrige(1, menor(heap, 0, 1));
  315. corrige(2, menor(heap, 1, 2));
  316. corrige(1, menor(heap, 0, 2));
  317. corrige(1, !menor(heap, 2, 1));
  318. corrige(2, !menor(heap, 2, 2));
  319.  
  320. /////////////
  321. // 12
  322.  
  323. corrige(4, ehHeapMin(heap));
  324.  
  325. heap->itens[0].id = 2;
  326. heap->itens[1].id = 1;
  327.  
  328. corrige(4, !ehHeapMin(heap));
  329.  
  330. destroiHeap(heap);
  331. heap = criaHeapMin(5);
  332. heap->itens[0] = *criaVendedor(1, 4);
  333. heap->itens[1] = *criaVendedor(2, 4);
  334. heap->itens[2] = *criaVendedor(3, 5);
  335. heap->itens[3] = *criaVendedor(4, 2);
  336. heap->itens[4] = *criaVendedor(5, 5);
  337.  
  338. corrige(4, !ehHeapMin(heap));
  339.  
  340. destroiHeap(heap);
  341.  
  342. /////////////
  343. // 15
  344.  
  345. heap = criaHeapMin(6);
  346. preencheHeap(heap,6, 1,0, 2,1, 3,2, 4,3, 5,4, 6,5);
  347. afunda(heap, 0);
  348. corrige(3, comparaHeap(heap,6, 1,0, 2,1, 3,2, 4,3, 5,4, 6,5));
  349.  
  350. preencheHeap(heap,6, 3,2, 1,0, 2,1, 4,3, 5,4, 6,5);
  351. afunda(heap, 0);
  352. corrige(3, comparaHeap(heap,6, 1,0, 3,2, 2,1, 4,3, 5,4, 6,5));
  353.  
  354. preencheHeap(heap,6, 3,2, 1,0, 2,1, 4,3, 5,4, 6,5);
  355. afunda(heap, 0);
  356. corrige(3, comparaHeap(heap,6, 1,0, 3,2, 2,1, 4,3, 5,4, 6,5));
  357.  
  358. preencheHeap(heap,6, 6,6, 1,1, 2,2, 3,3, 4,4, 5,5);
  359. afunda(heap, 0);
  360. corrige(3, comparaHeap(heap,6, 1,1, 3,3, 2,2, 6,6, 4,4));
  361.  
  362. preencheHeap(heap,6, 6,6, 1,1, 2,2, 4,4, 3,3, 5,5);
  363. afunda(heap, 0);
  364. corrige(3, comparaHeap(heap,6, 1,1, 3,3, 2,2, 4,4, 6,6));
  365.  
  366. destroiHeap(heap);
  367.  
  368. /////////////
  369. // 3
  370.  
  371. int *vendas;
  372. heap = inicializaProblemaHeap(5);
  373. vendas = inicializaProblemaVendas(5);
  374. fazChamada(heap, vendas, 2);
  375. fazChamada(heap, vendas, 2);
  376. fazChamada(heap, vendas, 1);
  377. corrige(1, comparaVetorInt(vendas,5, 1,1,1,0,0));
  378.  
  379. destroiHeap(heap);
  380. free(vendas);
  381.  
  382. heap = inicializaProblemaHeap(4);
  383. vendas = inicializaProblemaVendas(4);
  384. fazChamada(heap, vendas, 5);
  385. fazChamada(heap, vendas, 2);
  386. fazChamada(heap, vendas, 3);
  387. fazChamada(heap, vendas, 3);
  388. fazChamada(heap, vendas, 4);
  389. fazChamada(heap, vendas, 9);
  390. corrige(1, comparaVetorInt(vendas,4, 1,2,2,1));
  391.  
  392. destroiHeap(heap);
  393. free(vendas);
  394.  
  395. heap = inicializaProblemaHeap(3);
  396. vendas = inicializaProblemaVendas(3);
  397. fazChamada(heap, vendas, 3);
  398. fazChamada(heap, vendas, 5);
  399. fazChamada(heap, vendas, 1);
  400. fazChamada(heap, vendas, 1);
  401. fazChamada(heap, vendas, 1);
  402. fazChamada(heap, vendas, 1);
  403. fazChamada(heap, vendas, 1);
  404. fazChamada(heap, vendas, 1);
  405. fazChamada(heap, vendas, 1);
  406. corrige(1, comparaVetorInt(vendas,3, 3,1,5));
  407.  
  408. destroiHeap(heap);
  409. free(vendas);
  410.  
  411. printf("= %d\n", total);
  412.  
  413. return 0;
  414. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement