Comentário NOIC OBI 2017 - Fase 3 - Programação Nível 1

OBI 2017 - Fase 3 - Programação Nível Junior

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.

Zip

Comentário escrito por Vitor Veiga

Conhecimento prévio necessário:

O problema nos dá quatro valores de cartas. As duas primeiras são de Lia e as duas últimas são de Carolina. Queremos saber quem vai ganhar o jogo, ou se haverá empate, seguindo as seguintes regras para calcular a pontuação de cada uma:
Se C1 = C2, Pontuacao = 2 * (C1+C2);
Se C1 + 1 = C2, Pontuacao = 3 * (C1+C2);
Caso contrário, Pontuacao = C1 + C2.
Assim, a estratégia será ler a entrada, calcular a pontuação de cada uma das meninas por meio das regras e analisar quem fez mais pontos. Se elas realizarem a mesma pontuação, retornamos empate.

Clique aqui para conferir o código

Gomoku

Comentário escrito por Estela Baron

Conhecimento prévio necessário:

Nesse problema, o limite já vem estabelecido e é bem pequeno. Isso nos permite verificar, para toda casa, se ela faz parte de uma coluna, linha ou diagonal vencedora. Para isso, podemos analisar quatro casos:

  • se a casa atual é a primeira (esquerda para a direita) de uma linha vencedora: basta ir adicionando +1 no estado que corresponde ao eixo y e vendo se as quatro casas são iguais à atual.
  • se a casa atual é a primeira (cima para baixo) de uma coluna: basta ir adicionando +1 no estado que corresponde ao eixo x e vendo se as quatro casas são iguais à atual.

Cuidado para não acessar posições que não existem, por exemplo: m[4][16]. Só precisa analisar a posição se for diferente de zero. Outra coisa é que, desse jeito, conseguimos percorrer todas as linhas e colunas possíveis.

Para as diagonais, temos que analisar dois casos:

  • quando é do lado superior da direita para o lado inferior esquerdo: temos que ir adicionando +1 ao x e -1 ao y e ver se as quatro casas são iguais à atual.
  • quando é do lado superior esquerdo para o lado inferior direito: temos que ir adicionado +1 ao x e +1 ao y e ver se as quatro casas são iguais à atual.

Iniciamos a resposta como 0. Se as cinco posições, em algum caso, forem iguais, mudamos a resposta para a cor da pedra, 1 ou 2. Por fim, imprimimos a resposta.

Clique aqui para conferir o código

Visita entre Cidades

Comentário escrito por Enzo Dantas

Conhecimento prévio necessário:

Primeiramente, "os pares de cidades ligados diretamente por uma estrada são escolhidos de forma que sempre é possível ir de qualquer cidade para qualquer outra cidade por um, e somente um, caminho" significa que o grafo dado é uma árvore. Assim, o problema pede a distância entre dois vértices de uma árvore.

Isso pode ser achado usando uma DFS ou BFS: inicializamos a distância do vértice inicial A como 0 (dist[A] = 0). Quando estamos em um vértice u, dizemos que dist[v] = dist[u] + w, sendo w o peso da aresta u \rightarrow v.

A resposta do problema é a distância do vértice final B, ou seja, dist[B].

Clique aqui para conferir o código

Bits

Comentário escrito por Arthur Lobo

Conhecimento prévio necessário:

O problema nos pede para calcular quantas bitstrings (sequências com 0 e 1) existem com no máximo K 1's consecutivos. Problemas de contar quantos de uma coisa existem tem uma boa chance de serem resolvidos usando DP, e é o caso desse.

A DP usada para resolver esse problema será dp_{i,j} = quantidade de bitstrings válidas de tamanho i com j 1's consecutivos no final dela. O caso base da DP será:

  • dp_{0,0} = 1
  • dp_{0,x} = 0, para 1 \le x \le K

Normalmente nós tentamos fazer a transição calculando dp_{i,j} quanto estamos em i,j, que é chamado de DP push, mas para esse problema fica mais simples se considerarmos que já sabemos dp_{i,j} quando estamos em i,j, e então atualizamos o valor das próximas dp_{i+1,x} baseado em dp_{i,j}. Isso é chamado de DP pull.

Basta pensar como o valor de dp_{i,j} influencia no valor das próximas DP. Inicialmente sabemos os valores de dp_{0,x} e os valores de todas as outras dp começam sendo 0. Vamos usar dp_{0,x} para calcular dp_{1,x}, depois usar o de dp_{1,x} para o de dp_{2,x}, e assim até o final (para 0\le x \le K).

Quando estamos em i,j, com 1 \le i \le N e 0 \le j \le K, vamos fazer as seguintes transições:

  • Colocamos 0 na posição i+1, então a bitstring de tamanho i+1 vai terminar com 0 zeros \Rightarrow dp_{i+1,0}+= dp_{i,j}.
  • Colocamos 1 na posição i+1, então a bitstring de tamanho i+1 vai terminar com j+1 uns \Rightarrow dp_{i+1,j+1}+= dp_{i,j}. Nesse caso é preciso tomar cuidado quando j = K.

No final a nossa resposta vai ser a quantidade de bitstrings com qualquer valor entre 0 e K uns no final, então ela vai ser dp_{N,0}+ dp_{N,1} + ... + dp_{N,K}. Agora basta colocar um módulo 10^9+7 em tudo.

Clique aqui para conferir o código