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

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

Comentário por Lúcio Cardoso e Willian Wang

Para conferir a prova na íntegra, clique aqui.

Nota esquecida

Conhecimento prévio necessário:

Perceba que A+B = 2*M e B = 2*M - A.

Um possível erro é tentar calcular B usando divisão com variáveis inadequadas, como B=(M+A/2)*2 sendo A e M inteiros, por isso uma boa prática é sempre evitar a operação de divisão no código.

Complexidade: O(1).


// Comentário Noic OBI 2019 - Fase 2 - Programação Nível 1
// Nota esquecida
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a, m;
cin >> a >> m;
int b = m*2 - a;
cout << b << "\n";
}

view raw

nota.cpp

hosted with ❤ by GitHub

Tabela do campeonato

Conhecimento prévio necessário:

Note que, como o próprio enunciado indica, as duas equações abaixo tem de ser satisfeitas:

  1. J = V + E + D, e
  2. P = 3V + E.

O único caso que não possui solução (não pode ser determinado) é aquele com J = -1 e D = -1. Sequer precisamos nos preocupar com este caso, já que o enunciado garante que há uma solução possível. De resto, podemos manipular as equações acima e descobrir os valores de cada variável facilmente.

Assim, podemos usar apenas a estrutura if/else para conferir cada um dos possíveis casos e obter os valores corretos para cada variável desconhecida.

Complexidade: O(1).


// Comentário Noic OBI 2019 - Fase 2 - Programação Júnior
// Tabela do campeonato
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
int j, p, v, e, d;
cin >> j >> p >> v >> e >> d;
if (j == -1)
{
// o único caso impossível é j = -1 e d = -1
if (p == -1) p = 3*v+e;
else if (v == -1) v = (p-e)/3;
else if (e == -1) e = p-3*v;
j = v+e+d;
}
else if (p == -1)
{
// como os casos com j = -1 já foram vistos,
// sobram 3 casos (ou apenas p = -1)
if (v == -1) v = j-e-d;
else if (e == -1) e = j-v-d;
else if (d == -1) d = j-v-e;
p = 3*v+e;
}
else if (v == -1)
{
// os casos com j = -1 ou p = -1, já foram vistos,
// sobram 2 casos, (ou apenas v = -1)
if (e == -1)
{
// da 2a equação, E = P-3V -> J = V + P - 3V + D -> 2V = P+D-J
// -> V = (P+D-J)/2
v = (p+d-j)/2;
e = p-3*v;
}
else
{
v = (p-e)/3;
d = j-v-e;
}
}
else if (e == -1)
{
// sobra apenas o caso com e = -1 e d = -1 (ou apenas e = -1)
e = p-3*v;
if (d == -1) d = j-v-e;
}
else if (d == -1) d = j-v-e;
cout << j << " " << p << " " << v << " " << e << " " << d << "\n";
}

Jogo dos copos

Conhecimento prévio necessário:

Vamos utilizar três variáveis, A, B e C, que possuem valor 1 se a moeda estiver embaixo do copo representado por sua letra, ou 0 caso contrário.

Para trocar o valor de duas variáveis, efetuando cada uma das três possíveis operações, podemos utilizar o comando swap do C++: Ele recebe dois parâmetros, digamos, x e y, e realiza a troca dos seus valores em O(1). Como um exemplo, se x = 2 e y = 0, o comando swap(x, y) faz com que x = 0 e y = 2.

Complexidade: O(n).

https://gist.github.com/luciocf/9a3ffc6d01e0eefb2ed4c7fe3f4e5297​


// Comentário Noic OBI 2019 - Fase 2 - Programação Júnior
// Jogo dos copos
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
int n;
char copo; // copo em que a moeda está inicialmente
cin >> n >> copo;
int A = 0, B = 0, C = 0;
if (copo == 'A') A = 1;
else if (copo == 'B') B = 1;
else C = 1;
for (int i = 1; i <= n; i++)
{
int operacao;
cin >> operacao;
if (operacao == 1)
swap(A, B); // troca A e B
else if (operacao == 2)
swap(B, C); // troca B e C
else
swap(A, C); // troca A e C
}
if (A == 1) cout << "A\n";
else if (B == 1) cout << "B\n";
else cout << "C\n";
}