Comentário NOIC OBI 2018 - Fase 2 - Programação Nível Júnior

OBI 2018 - Fase 2 - Programação Nível Júnior

Para conferir a prova na íntegra, clique aqui

Para ver todos os materiais incrível produzidos pela equipe NOIC para a OBI, veja a página de informática.

Copa

Comentário escrito por Enzo Dantas

Conhecimento prévio necessário:

A ideia é a seguinte, seja a, b as posições dos jogadores Mestre Kung e Mestre Lu:

  • Dois jogadores vão se encontrar na final se, um deles estiver entre [1, 8] e outro estiver entre [9, 16], pois senão, eles vão ter se encontrado antes. Portanto, se isso for verdade, vamos retornar "final" no nosso código e parar o algoritmo.
  • Agora, se os dois estiverem entre [9, 16], vamos fazer a = a-8 e b = b-8, e então, os dois jogadores vão estar entre [1, 8]. Veja que isso não vai mudar a resposta do problema, pois a estrutura do torneio para [1, 8] é a mesma para [9, 16]. (A partir daqui, as ideias são análogas).
  • Dois jogadores vão se encontrar na semifinal se, um deles estiver entre [1, 4] e outro estiver entre [5, 8], então, se isso for verdade, vamos retornar "semifinal" no nosso código e parar o algoritmo.
  • Se os dois estiverem entre [5, 8], vamos fazer a = a-4 e b = b-4, e então, os dois jogadores vão estar entre [1, 4].
  • Dois jogadores vão se encontrar nas quartas de final se, um deles estiver entre [1, 2] e outro estiver entre [3, 4], então, se isso for verdade, vamos retornar "quartas" no nosso código e parar o algoritmo.
  • Se os dois estiverem entre [3,4], vamos fazer a = a-2 e b = b-2, e então, os dois jogadores vão estar entre [1, 2].
  • Daí, basta retornar oitavas.

Por exemplo, no sample 5, 8, veja que eles não vão se encontrar na final, e ambos estão entre [1, 8]. Além disso, eles não vão se encontrar na semifinal, e eles estão entre [5, 8], logo vamos olhar o par 1, 4. Então, sabemos que eles vão se encontrar nas quartas.

Clique aqui para conferir o código

Clique aqui para conferir a solução em vídeo feita pelo NepsAcademy

Pesos

Comentário escrito por Estela Baron

Conhecimento prévio necessário:

Observe que, para subir um peso grande, é necessário já ter um peso menor (ou nenhum) cuja a diferença seja menor ou igual a 8. Portanto, podemos adotar a seguinte estratégia: vamos fazer uma série de operações para subir o maior peso, pois depois subiremos o segundo maior, o terceiro maior e assim por diante. Isso somente é possível em razão de o número de viagens não ter nenhuma restrição.

Para subir o maior peso, caso ele seja maior que 8, é necessário que tenha uma caixa mais leve (se fosse mais pesada, o atual peso não seria o maior - estamos só considerando movimentar os pesos menores que o maior). A diferença é no máximo 8, ou seja, a segunda caixa mais pesada pode ter uma diferença de no máximo oito unidades. Assim, podemos ordenar os valores em ordem crescente ( podemos até incluir o 0 para representar o elevador vazio) e verificar se a diferença entre dois termos adjacentes não ultrapassa 8. Caso ultrapasse, a resposta é 'N', senão é 'S'.

Clique aqui para conferir o código

Clique aqui para conferir a solução em vídeo feita pelo NepsAcademy

Cápsulas

Comentário escrito por Caique Paiva

Conhecimento prévio necessário:

Seja f(p) a quantidade de moedas que ganhamos até o dia p. Veja que

f(p) \ge f(p-1)

Pois, se até o dia p-1 ganhamos k moedas, então, no dia p, como é impossível de perder moedas no problema, continuamos com pelo menos k moedas. Então, f é crescente. Agora, veja que

f(p) = \sum_{i = 1}^n \lfloor \frac{n}{c_i} \rfloor

Pois, no dia c_i, 2c_i, 3c_i, \cdots xc_i ganhamos uma moeda em cada dia, isso até xc_i \le n \rightarrow x \le \frac{n}{c_i}, e o x máximo que isso é verdade é o \lfloor \frac{n}{c_i} \rfloor, então, basta aplicar isso para todas as moedas e somar todas as respostas, que conseguimos f(p).

 

Portanto, queremos achar o menor p tal que f(p) \ge F, e além disso, sabemos como calcular f(p) em O(n) e que f é crescente, então, vamos fazer uma busca binária!! Faça l = 0, r = 10^{18}, então, vamos fazer o seguinte loop:

  • Enquanto l < r, seja mid = \frac{l+r}{2}, logo, se f(mid) \ge F, então, façamos r = mid, pois sabemos que f(x) \ge f(mid) \ge F \forall x > mid. Se não, faça l = mid +1, pois sabemos que F > f(mid) \ge f(x) \forall x < mid.

Daí, basta retornar l.

Clique aqui para ver o código

Clique aqui para conferir a solução em vídeo feita pelo NepsAcademy