OBI 2024 – Fase 2 – Programação Nível 2 – Turno B

OBI 2024 – Fase 2 – Programação Nível 2 – Turno B

Se você quiser se preparar para a OBI, não deixe de conferir o Roteiro de estudos de informática, e também a página de informática do NOIC, com todos nossos materiais.

Game Show

Escrito por Caique Paiva

Conhecimentos Prévios Necessários:

Basta fazermos o que o problema pediu. Mantenha uma variavel chamada resposta, e inicialize ela com $$0$$. Então, quando estou lendo o caractere $$i$$:

  • Caso seja $$E$$, faça $$resposta *= 2$$
  • Caso contrário, faça $$resposta = 2*resposta+1$$

Clique aqui para ver o código

Salada de Frutas

Comentário por Fernando Gonçalves

Conhecimento Necessário:

Nesse problema, temos que achar, dada uma quantidade de dinheiro e os preços de diversas frutas, qual a máxima quantidade de tipos de fruta que podemos comprar.

Dessa forma, para um tipo de fruta, só precisamos considerar o menor preço disponível para a sua compra. Os demais preços de um mesmo tipo são irrelevantes, pois não faz sentido gastarmos mais do que o necessário na compra de uma fruta.

Agora, sabemos os preços que estamos dispostos a pagar por cada fruta, então só precisamos decidir quais nós compraremos.

Para maximizar a quantidade comprada, podemos escolher as frutas gulosamente, sempre escolhendo aquela de menor preço. A prova desse guloso é pelo argumento da troca: se eu tivesse comprado uma fruta de preço maior quando havia alguma com preço menor disponível, trocar a minha escolha para o preço menor não pode piorar a resposta.

Em suma, vamos guardar o menor preço de toda fruta, e comprá-las na ordem de preço crescente.

Clique aqui para conferir o código

Trio de Palitos

Escrito por João Pedro Castro

Conhecimentos Prévios Necessários:

Subtask 1 (30 pontos): $$N \leq 100$$

Podemos simplesmente testar todas as triplas $$i < j < k$$ e somar $$1$$ à resposta toda vez que conseguirmos formar um triângulo. Complexidade é $$O(n^3)$$.

Subtask 2 (24 pontos): Existem exatamente dois tamanhos de palitinhos

Essa subtarefa é mais chata e envolve basicamente só combinatória. Vamos chamar um desses tamanhos de $$a$$ e o outro de $$b$$; enquanto a quantidade de palitinhos de tamanho $$a$$ é $$q_a$$ e analogamente a quantidade de palitinhos de tamanho $$b$$ é $$q_b$$. Ambos valores são facilmente calculáveis com um loop.
Primeiro, percebam que podemos formar triângulos equiláteros com somente um tipo dos palitinhos. Logo vamos adicionar à resposta $${q_a \choose 3} = \frac{q_a \cdot (q_a – 1) \cdot (q_a – 2)}{6}$$; e a mesma coisa pro $$q_b$$.

Agora vamos analisar o outro caso, que é quando temos dois palitos de um tamanho e um de outro tamanho. Vamos resolver tratando como dois de tamanho $$a$$ e um de tamanho $$b$$, e depois vocês podem fazer a mesma coisa trocando os dois. Primeiro, se $$2 \cdot a < b$$ não somamos nada. Agora caso contrário, a quantidade possível é $${q_a \choose 2} \cdot q_b$$. Fica como exercício para o leitor expandir essa conta (aprendam a escolhe b!).

A complexidade é $$O(n)$$.

Subtask 3 (17 pontos): $$A_i \leq 100$$

Essa é uma solução generalizada da subtask acima. Chame de $$q_x$$ como a quantidade de elementos com valor $$x$$. Vamos brutar todas essas possibilidades:

  • Usar só um $$i$$: $${q_i \choose 3}$$
  • Usar dois $$i$$ e um $$j$$, com $$i \neq j$$ e $$2*i > j$$: $${q_i \choose 2} \cdot q_j$$
  • Usar um $$i$$, um $$j$$ e um $$k$$, com $$i < j < k$$ e $$i + j > k$$: $$q_i \cdot q_j \cdot q_k$$

Complexidade é $$O({A_i}^3)$$.

Subtask 4 (full): $$N \leq 1500$$

Vamos ordenar o vetor. Agora temos que escolher três posições, vamos fixar a do meio como $$i$$ e dizer que elas são $$l < i < r$$. Para cada $$i$$ queremos achar todos os pares $$l < r$$ que satisfazem $$A_l + A_i > A_r$$.

Imagine que fixamos o $$l$$, e chamamos o valor máximo de $$r$$ que satisfaz a condição como $$mx_l$$. A observação que permite o uso do two pointers é a de que $$mx_l \geq mx_{l-1}$$. A prova é trivial e deixada como exercício para o leitor.

Então, para cada $$i$$ vamos começar com $$r := n$$. Agora, para cada $$0 \leq l < i$$, começando com $$l := i – 1$$ vamos fazer o seguinte loop:

  • Enquanto $$r > i$$ e $$A_l + A_i \leq A_r$$: $$r := r – 1$$

Após rodar o loop para cada $$l$$ somamos a resposta $$r – i$$, já que todas as $$r – i$$ posições $$i + 1, i + 2, …, r$$ são $$r$$ válidos para a nossa equação.

Como para cada $$i$$ fazemos $$O(n)$$ operações (temos um valor que vai de $$i-1$$ até $$0$$ e outro que vai de $$n$$ até $$i$$), a complexidade final é $$O(n^2)$$.

Clique aqui para ver o código

Dígitos

Escrito por Caique Paiva

Conhecimentos Prévios Necessários:

Vamos definir como $$dp[i]$$ para ser o número mínimo de rodadas para ir de $$i$$ para $$0$$. Vamos calcular a dp de forma iterativa, então, quando formos calcular a resposta para $$dp[i]$$, já temos calculada $$dp[j]$$ com $$j < i$$. Agora, vamos pegar todos os dígitos de $$i$$ (Para isso, basta fazer um while em que pega o resto de $$i$$ por $$10$$ e divide-o por $$10$$), e testar subtrair cada um deles, e então, $$dp[i] = min(dp[i-d])+1$$, onde $$d$$ é um dígito de $$i$$, e tiramos o mínimo pois queremos pegar a menor resposta possível. Depois disso, basta imprimir $$dp[n]$$.

Clique aqui para ver o código (Fun fact: Esse problema já existia antes da prova)