AED 2021/2022 (L.EIC011)

Mooshak #02 - Ordenação e Pesquisa Binária
(semana de 15/11 a 19/11)


Nota Inicial

Os exercício do Mooshak desta aula não contam para nota e são completamente opcionais (a vossa prioridade deve ser primeiro completar os exercícios base das aulas práticas). Os exercícios aqui colocados destinam-se a quem quer ir mais além do que requisitos mínimos e quiser ter uma camada de submissão com avaliação automática, sendo que todas as semanas iremos colocar disponíveis novos problemas.

Para tornar tudo um pouco mais interessante, eu (Pedro Ribeiro) deixo desde já prometido que irei pagar uma refeição na minha companhia (uma francesinha no Capa Negra II) a três estudantes desta UC:

Espero para ver os vosses "dotes" algorítmicos ao longo destas semanas! :)


Problemas para submissão


Nesta unidade curricular vamos usar o sistema Mooshak como uma maneira opcional e adicional para avaliar automaticamente código.

Nesta aula foram disponibilizados os seguintes problemas:


Exercício 1) Usando a biblioteca do C++ linguagem para ordenar

A ordenação é uma operação "básica" essencial em muitos algoritmos. É por isso comum que uma qualquer linguagem de programação tenha disponível na sua biblioteca padrão uma função de ordenação. O C++ não é excepção e o objectivo deste exercício é levá-lo a conhecer como ordenar usando o sort disponível:

  1. Tem ao seu dispor um pequeno programa que mostra como ordenar números inteiros: sort.cpp. Experimente compilar e executar na sua máquina, garantindo que percebe o programa.
  2. A mesma função de ordenação pode ser usada para quaisquer outros tipo primitivos. Experimente mudar o programa para outro tipo primitivo (ex: double ou char) e execute para verificar que a ordenação continua a funcionar.

Exercício 2) Ordenação com um critério personalizado

Por vezes queremos ordenar por um critério diferente do padrão (ex: por ordem decrescente; ordenar primeiro por um campo e depois por outro). Nesses casos queremos poder usar o sort da biblioteca, mas passar-lhe um comparador "customizado" que permita ordenar segundo o critério que desejamos.

  1. Tem ao seu dispor um pequeno programa para ordenar pessoas por ordem crescente da idade e em caso de empate por ordem alfabética do nome: customsort.cpp. Tem também disponível um ficheiro com um exemplo de input para poder testar o programa: persons.txt. Experimente compilar e executar na sua máquina, garantindo que percebe o programa.
  2. O que precisaria de alterar no programa para ordenar por ordem decrescente da idade (ao invés da ordem crescente)? Experimente mudar, compilar e executar para testar o que pensou.
  3. Usando o que aprendeu, leia, resolva e submeta no Mooshak o problema [AED 05] ADN Alienígena .


Exercício 3) Um problema com pesquisa binária "clássica"

Comece por ler o enunciado do problema [AED 06] Somas mais próximas. O objectivo final deste exercício é conseguir submeter com sucesso uma solução. Em vez de considerar que são possíveis spoilers, neste problema queremos mesmo que siga os passos que sugerimos.

  1. Vamos começar por calcular todos as somas possíveis de pares de números. Se temos n números guardados num vector v[], queremos todos os pares v[i] + v[j] com 0 ≤ i, j ≤ n-1.
    1. Exactamente quantos pares existem? Qual a sua ordem de grandeza em termos assintóticos?
    2. Implemente dois ciclos para guardar estes pares num novo vector somas[] e confirme que a quantidade de pares é a que calculou.
  2. Para cada uma das Q perguntas vamos querer agora pesquisar no vector pares[] procurando a(s) soma(s) mais próxima(s).
    1. Uma alternativa seria fazer uma simples pesquisa linear (um ciclo percorrendo todos os elementos de pares). Será que isto passaria no tempo necessário? Porquê?
    2. O vector de somas é igual para todas as perguntas pelo que podemos pré-processar para depois melhorar a pesquisa. Sendo assim, podemos precisamente... ordená-lo! Use a biblioteca padrão de C++ ordenar o array.
    3. Depois de ter ordenado, podemos aplicar... pesquisa binária! É no entanto necessário cuidado porque o número que procuramos pode não estar no array. O que queremos realmente é o número mais próximo do que procuramos.
  3. No final, o esquema geral do algoritmo para este problema é o seguinte:

Exercício 4) Um problema com pesquisa binária "indirecta" (binary search the answer)

Implemente e submeta uma solução para o problema [AED 07] Viagem de mochila às costas.

Use o algoritmo explicado nas aulas teóricas (ver slides da teórica 5 - algoritmos de pesquisa em vetores, The Painter’s Partition Problem, slides 11 a 14; em alternativa pode ver slides equivalentes de uma unidade curricular do DCC/FCUP: ver slides 27 a 36 ou em vídeo.


Exercício de Desafio

Todas as semanas vou colocar disponível pelo menos mais um exercício um pouco mais desafiante.

Para esta semana o desafio é diferente do habitual, sendo um problema de output-only, pelo que pode resolvê-lo usando uma qualquer linguagem de programação (ou até fazendo manualmente). O problema está disponível para submissão no Mooshak:

Se já tiverem feito tudo e estiverem "presos" neste, e quiserem mesmo fazer o desafio, podem contactar-me para eu "dosear" as dicas, sabendo que este problema é substancialmente mais difícil os outros desta aula.

Depois de terem submetido não deixem de falar comigo no Slack para explicarem as vossas ideias, uma vez que não vou ter acesso ao código que usaram para gerar a resposta :)