Comentário NOIC OBOI 2023 – Fase 2 – Nível Júnior

OBOI 2023 – Fase 2 – Nível Júnior

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.

Para conferir a prova na íntegra, clique aqui.

Par de Palitinhos

Comentário escrito por Estela Baron

Conhecimento prévio necessário:

Como o problema nos garante que os palitinhos estão em ordem crescente, podemos armazenar qual era o tamanho do palito anterior e calcular a diferença entre o palito atual com o anterior. Veja que a menor diferença entre um palito é, ou o palito seguinte, ou o anterior. Caso a diferença calculada seja menor que o menor valor que achamos anteriormente, atualizamos a resposta. Observe também que só podemos calcular a diferença do anterior a partir do segundo palito. Ao final, basta imprimir a resposta.

Clique aqui para conferir o código.

Cifra

Comentário escrito por João Pedro Castro

Conhecimento prévio necessário:

Vamos denotar o i-ésimo caractere de uma string $$S$$ como $$S_i$$ (0-indexado). A ideia da solução é simplesmente checar se a “distância” entre todos os pares de caracteres $$S_i$$ e $$T_i$$ são a mesma para todo $$0 \leq i < |S, T|$$. Para realizar isso, podemos simplesmente guardar a distância entre os primeiros caracteres de ambas strings, $$S_0$$ e $$T_0$$, e depois adicionar essa distância à todo $$T_i$$ e confirmar se após isso ele é o mesmo caractere que $$S_i$$.

Para não termos distâncias negativas, se $$S_0 < T_0$$ dizemos que $$S := T$$ e que $$T := S$$ simultaneamente (ou seja, trocamos elas de lugar); e para somar essa distância $$d$$ nos $$T_i$$ podemos transformar eles em valores númericos entre $$0$$ e $$25$$ fazendo $$T_i – \text{‘A’}$$, e então somar a esse valor a distância $$d$$, e depois pegar o módulo $$26$$ disso, para que caso passe da letra Z ele volte para o A. Logo, o caractere após a soma vai ser $$((T_i – \text{‘A’}) + d + \text{‘A’})~mod~26$$, e se esse valor for igual a $$S_i$$ para todo $$T_i$$, a resposta é ‘S’, caso contrário a resposta é ‘N’.

Clique aqui para conferir o código

Entrega de Mantimentos

Comentário escrito por Enzo Dantas

Conhecimento prévio necessário:

Subtask 1

Para os limites pequenos, podemos calcular em O(N) a resposta para cada coordenada entre (0,0) e (100,100).

Solução completa

Intuitivamente, imaginamos um ponto no plano e qual seria a resposta para ele. Deslizando esse ponto livremente, chegamos a primeira observação: se movermos um ponto para a esquerda/direita, as distâncias verticais não mudam, apenas as horizontais (a situação análoga acontece ao deslizar o ponto para cima/baixo). Logo, é possível calcular as coordenadas X e Y independentemente.

Assim, o problema foi reduzido para o seguinte: dados vários pontos numa linha, retorne um ponto qualquer que minimiza o somatório das distâncias aos outros pontos. Seguindo a idea de imaginar um ponto e deslizá-lo pelo plano, percebemos o seguinte: quando o deslizamos 1 unidade para a direita, por exemplo, o somatório aumenta em 1 para cada ponto a sua esquerda e diminui em 1 para cada ponto a sua direita. Assim, se há mais pontos a direita, vale a pena deslizar para a direita e vice-versa. Logo, o ponto ótimo fica em uma posição tal que há metade dos pontos a sua esquerda e metade a sua direita (ou seja, a mediana), pois qualquer movimentação dele diminuiria ou não mudaria o somatório. Para o caso em que N é par, os dois pontos centrais são ótimos. Como o enunciado pede para maximizar o X em caso de empate, retornamos o mais a direita.

Logo, a solução final consiste em separar as coordenadas X e Y em dois arrays diferentes, ordená-los, e retornar as duas medianas.

Clique aqui para conferir o código

Tomando Almas

Comentário escrito por Estela Baron

Conhecimento prévio necessário:

Parcial:

Vamos chamar de $$X$$ a quantidade de exercícios do tipo A. Podemos testar para todos os valores de $$X$$ de 0 até k qual é a quantidade de instrutores que podem ser impressionados com $$X$$ exercícios do tipo A e $$k – X$$ exercícios do tipo B. Assim, guardamos a maior quantidade. Para isso, para cada $$X$$, vamos verificar se a pessoa $$i$$ tem $$a_i$$ menor ou igual a $$X$$ ou $$b_i$$ menor ou igual a $$k – X$$. A complexidade fica $$O(N*K)$$.

Solução total:

Vamos chamar de $$X$$ a quantidade de exercícios do tipo A. Observe que podemos enxergar isso como uma soma de prefixos: é possível impressionar o $$instrutor_i$$ se $$X$$ for maior ou igual a $$a_i$$ ou se $$k-X$$ for maior ou igual a $$b_i$$. Ou seja, podemos escolher o $$instrutor_i$$ para intervalos de $$a_i$$  até $$k$$ – quando impressionamos pelo valor de $$a_i$$. Também conseguimos escolher o $$instrutor_i$$ para intervalos de $$X$$ de $$0$$ até $$k – b_i$$ – quando conseguimos impressionar pelo valor de $$b_i$$.

No entanto, é possível que, para determinado valor de $$X$$, tanto $$a_i$$ quanto $$b_i$$ sejam contados. Com isso teríamos uma contagem repetida. Por isso, precisamos retirar os intervalos em que as duas condições são atendidas. Observe que, quando escolhemos usar o $$b_i$$, ficamos com $$k – b_i$$ exercícios para $$a_i$$. Logo, essa diferença equivale ao valor máximo de $$X$$ que podemos escolher de tal forma que dê para cumprir tanto $$a_i$$ quanto $$b_i$$.

Logo, a nossa soma de prefixos será calculada da seguinte forma: só iremos colocar as posições que nos interessam (para não estourar a memória e o tempo). Vamos adicionar +1 em cada $$a_i$$. Se $$b_i$$ não ultrapassar $$k$$, vamos adicionar +1 no valor $$0$$ e -1 no valor $$k – b_i + 1$$. Com a soma acumulada, teremos a soma de pessoas. Para tirar as pessoas que contamos duas vezes, vamos adicionar -1 em $$a_i$$ e adicionar +1 em $$k – b_i + 1$$. Lembrando que só será preciso tirar os valores repetidos se $$a_i + b_i$$ forem menores ou igual a $$k$$.

Para fazer a soma acumulada, foi utilizado um vector e, em seguida, ele foi ordenado. Então a complexidade ficou $$O(NlogN)$$.

Ao final, fazemos a soma acumulada e guardamos a maior resposta.

Clique aqui para conferir o código.