OBI 2021 - Fase 2 Turno A - Programação Nível 1
Para se preparar para a OBI, confira o nosso Roteiro de Estudos, nele você vai encontrar um direcionamento completo de como estudar!
Comentário escrito por Pedro Racchetti, Lúcio Figueiredo, Luca Dantas e Thiago Mota
Para conferir a prova na íntegra, clique aqui.
Duplas de Tênis
Conhecimento prévio necessário:
Primeiro, para simplificar a solução, chamaremos os jogadores de ,
,
e
. Para este problema, nota-se que só temos 3 configurações possíveis de duplas:
e
;
e
;
e
.
Portanto, basta testar a diferença dos valores para cada configuração, e imprimir a menor delas.
A complexidade da solução é . Segue o código, comentado, para melhor compreensão:
Retângulo
Conhecimento prévio necessário:
Para resolver o problema, vamos utilizar a seguinte observação:
Observação: Um quadrilátero demarcado em um círculo é um retângulo se e somente se as diagonais
e
são diâmetros do círculo.
Com esta observação, basta sabermos se existem quatro pontos no círculo tais que os segmentos
e
são diâmetros, ou seja, a soma dos arcos de
a
e a soma dos arcos de
a
ambas valem metade da circunferência do círculo.
Defina como a soma dos arcos entre os pontos
e
, ou seja,
. Além disso, defina
como o ponto
tal que o segmento
é um diâmetro, ou
caso não exista. Vamos computar, para cada ponto
, o seu valor
. Pela definição de diâmetro, teremos que
é um diâmetro se e somente se
vale metade da circunferência, ou seja,
. Portanto, para encontrar o ponto
(se existir), podemos utilizar uma busca binária no intervalo
. Para calcularmos os valores
de forma eficiente, basta precalcularmos a soma de prefixo do vetor
; assim, se
é a soma do
-ésimo prefixo, conseguimos calcular
em
, já que
.
Após computarmos os valores , resta apenas checar se existem dois pontos
e
tais que
e
. Se sim, existe um retângulo demarcado no círculo formado por
e
. Senão, não existe retângulo algum.
Já que realizamos uma busca binária para cada um dos pontos, a complexidade da solução é
. Confira o código abaixo para melhor entendimento:
PS.: Existe uma solução com complexidade , utilizando a técnica de Two Pointers para encontrar os valores
. Como exercício, tente implementar esta solução!
Robô
Conhecimento prévio necessário:
Neste problema, precisamos apenas simular a ação do robô, adicionando um valor à resposta a cada vez que ele passar pela estação desejada.
Para simular o movimento, basta andarmos na direção que a entrada do problema nos indica (1 anda para a direita, -1 anda para esquerda). Para manter a propriedade circular, podemos utilizar uma de duas técnicas: na primeira, utilizaremos um if para checar se uma posição é menor que ou maior que
, e assim atribuí-la para o valor correto do outro lado do círculo (se for
vira
, se for
vira
). A outra possibilidade é salvar os valores
-indexados (de
a
) e utilizar o operador de módulo para atribuir o valor correto.
A complexidade da solução é . Para melhor entendimento, confira os códigos abaixo, que implementam as duas maneiras de resolver o problema, mencionadas acima:
Solução 1, utilizando if
Solução 2, utilizando módulo
Média e Mediana
Conhecimento prévio necessário:
Para que a média seja igual a mediana, basta que a distância do elemento do meio para as pontas seja a mesma, por exemplo:
, a distância do
para as pontas é a mesma, logo a média e a mediana ficam no mesmo ponto. Podemos demonstrar isso matematicamente:
Pegue 3 números em ordem não-decrescente , onde
é a mediana. Para que a média seja igual a mediana precisamos é necessário que
. Logo podemos abrir a conta e chegar na conclusão apresentada acima.
Para resolver o problema, basta escolher qualquer número de tal forma que a diferença entre o maior e o menor seja igual o do meio. Segue o código: