Olá meus amigos nerds, depois de um bom hiato, devido a eu ter me mudado e ficado algum tempo sem internet :(, estamos de volta para resolver mais problemas.
Mas para compensar hoje vamos resolver um tipo de problema que eu gosto muito: um problema que a solução fácil, não é suficientemente boa, nos forçando a ir além e fazer melhor.
Hoje vamos verificar qual a cor que mais aparece durante um desfile de patos. Já que é isso que o problema 17384. Desfile dos Patos nos pede. Mais especificamente, dada uma fila de patos, em que cada pato tem uma plumagem de cor diferente, determinar qual é a cor majoritária dentre as cores da plumagem dos patos, isto é, a cor que aparece em mais da metade das plumagens.
Solução
Apesar da aparente simplicidade esse problema é bem difícil. Ele possuí um limite de tempo muito apertado, e isso faz com que algo que geralmente não é muito importante, quando tratamos de complexidade de algoritmos, se tornar relevante, as constantes.
Vocês já devem ter percebido que um simples mapa resolve o problema, isto é armazene contadores para cada cor e no final verifique qual cor majoritária. Se implementarmos o mapa como um hash, esse algoritmo é linear. Além disso, ele tem complexidade ótima, já que não é possível resolver esse problema sem analisar cada elemento da lista.
Entretanto o algoritmo acima não é eficiente o suficiente para resolvermos esse problema. Quem diria, um hash não é eficiente o suficiente para resolve-lo! Depois de muito pensar (e até achar que quem inseriu o problema cometeu algum equivoco no time limit), observamos que o problema tem uma característica especial, a cor mais frequente é majoritária, isso é ela tem mais aparições na lista que a soma de todas as outras cores. Isso nos permite abrir mão do hash e usar um único contador para verificar qual é a cor majoritária.
A ideia é a seguinte, se do número de aparições da cor majoritária subtrairmos o número de aparições de cada uma das outras cores, esse resultado é necessariamente maior que 0. Assim, podemos usar um algoritmo guloso para contar a diferença entre o número de aparições da cor majoritária para as outras cores. Podemos iniciar nossa contagem com qualquer cor, já que ao final necessariamente a cor majoritária tem elementos o suficiente para "cancelar" com cada um dos elementos das outras cores. O algoritmo abaixo vai verificando qual a cor majoritária até a 0-ésima posição do vetor, 1-ésima posição, ..., n-ésima, etc
corMajoritaria = 0
cnt = 0
for cor in corPatos
if cnt == 0
corMajoritaria = cor
if cor == corMajoritaria
cnt++
else
cnt--
O algorítmo acima é mais eficiente que um hash, pois não tem que pagar o custo de iterar sobre todos os elementos do hash ao final para verificar qual é o que tem o maior contador.
A ideia é a seguinte, se do número de aparições da cor majoritária subtrairmos o número de aparições de cada uma das outras cores, esse resultado é necessariamente maior que 0. Assim, podemos usar um algoritmo guloso para contar a diferença entre o número de aparições da cor majoritária para as outras cores. Podemos iniciar nossa contagem com qualquer cor, já que ao final necessariamente a cor majoritária tem elementos o suficiente para "cancelar" com cada um dos elementos das outras cores. O algoritmo abaixo vai verificando qual a cor majoritária até a 0-ésima posição do vetor, 1-ésima posição, ..., n-ésima, etc
corMajoritaria = 0
cnt = 0
for cor in corPatos
if cnt == 0
corMajoritaria = cor
if cor == corMajoritaria
cnt++
else
cnt--
O algorítmo acima é mais eficiente que um hash, pois não tem que pagar o custo de iterar sobre todos os elementos do hash ao final para verificar qual é o que tem o maior contador.
Acredito que tenha um erro no algoritmo apresentado e também um erro no enunciado do problema. Dada entrada 5, 2 2 3 4 5 de acordo com o algoritmo apresentado a cor predominante seria 5 erradamente. No enunciado não como devemos tratar entradas que não resulte em um cor predominante.
ResponderExcluirAcredito que tenha um erro no algoritmo apresentado e também um erro no enunciado do problema. Dada entrada 5, 2 2 3 4 5 de acordo com o algoritmo apresentado a cor predominante seria,erradamente, 5 . No enunciado não como devemos tratar entradas que não resulte em uma cor predominante.
ResponderExcluiropa,
Excluirbão demais Gilson :D Valeu pelo comentário.
Acho que a solução não está incorreta não.
Vamos tentar explicar um pouquinho :)
O problema garante que existe uma cor majoritária. Isso quer dizer que dentre as cores apresentadas, existe uma que é mais frequente que todas outras cores somadas.
E como isso não acontece com a entrada que vc sugeriu, ou seja, a entrada que você sugeriu é INVALIDA. Para ela ser válida a cor 2 teria que aparecer pelo menos 3 vezes.
Perceber esse detalhe é justamente o diferencial desse problema. Ele foi um problema pensado para forçar vc a ir um pouco além do uso dos algorítmos clássicos de hash :)
espero que tenha ajudado e desculpa por demorar a responder, ando bem sem tempo atualmente rsrsrs