Comentário Noic OBI 2020 - Fase 1 Turno A - Programação Nível Júnior

Comentário por Anita Ramos

Para conferir a prova na íntegra, clique aqui.

Piloto Automático

Conhecimento prévio necessário:

Esse é um problema bem simples, que pode ser resolvido apenas com comandos de condição, como if e else. Assim, depois de declarar as variáveis e ler toda a entrada, utilizamos as fórmulas dadas pelo próprio enunciado para verificar o que deve ser feito com a velocidade. Assim:

  • Se (B-A)<(C-B), B desacelera;
  • Se (B-A)>(C-B), B acelera;
  • Se (B-A)=(C-B), B mantém a velocidade.

Complexidade: O(1).

Segue o código comentado para melhor compreensão da solução:


#include<bits/stdc++.h> //biblioteca utilizada
using namespace std;
int main()
{
int A,B,C; //declaração das variáveis
scanf("%d", &A); //leitura da 1º linha de entrada
scanf("%d", &B); //leitura da 2º linha de entrada
scanf("%d", &C); //leitura da 3º linha de entrada
if((B-A)<(C-B))printf("1"); //se a distancia entre 'A' e 'B' é menor que a distancia entre 'C' e 'B', imprimi 1
if((B-A)>(C-B))printf("-1"); //se a distancia entre 'A' e 'B' é maior que a distancia entre 'C' e 'B', imprimi -1
if((B-A)==(C-B))printf("0"); //se as distancias entre 'A' e 'B' e entre 'C' e 'B' forem iguais, imprimi 0
return 0; //retorna a 0
}

view raw

Piloto.cpp

hosted with ❤ by GitHub

Entrega de Caixas

Conhecimento prévio necessário:

Diferentemente do problema anterior, este já exige que você estabeleça uma lógica de verificação (por mais que seja intuitivo). Assim, podemos estabelecer que:

  • Se os tamanhos das caixas forem iguais, imprimi 3;
  • Se não existir nenhum tamanho igual entre as caixas, imprimi 1 (já que uma cabe dentro da outra);
  • Se duas das caixas são iguais e cabem lado a lado dentro da terceira, imprimi 1;
  • Se nenhuma das possibilidades acima for verdade, imprimi 2. Por exemplo, para A<B e B=C, A cabe em C ou em B, mas B e C precisam de viagens diferentes por serem do mesmo tamanho. Assim, um caso possível é A e B na mesma viagem e C em outra.

É importante ressaltar o uso de return 0; no final de cada verificação, já que um caso, sem esse comando, imprimiria a resposta correta e em seguida o número 2 (se nenhuma possibilidade for aceita) e que podemos juntar a 2º e a 3º verificações em apenas uma, com o uso de OU, representado por ||.

Complexidade: O(1).

Segue o código comentado para melhor compreensão da solução:


#include<bits/stdc++.h> //biblioteca utilizada
using namespace std;
int main()
{
int A,B,C; //declaração das variáveis
scanf("%d %d %d", &A, &B, &C); //leitura da entrada
if(A==B && B==C) //se 'A'='B'='C'
{
printf("3"); //imprimi 3
return 0; //retorna a 0 (encerra)
}
if((A<B && B<C) || (A==B & A+B<C)) //se ('A'<'B'<'C') OU ('A'='B' && 'A'+'B'<'C')
{
printf("1"); //imprimi 1
return 0; //retorna a 0 (encerra)
}
printf("2"); //se nada é verdade, imprimi 2
return 0; //retorna a 0 (encerra);
}

view raw

Caixas.cpp

hosted with ❤ by GitHub

Escher

Conhecimento prévio necessário:

Esse problema já envolve vetores e a ideia de analisá-los aos pares "opostos". Assim, depois de declarar a biblioteca, declarar um vetor de tamanho extenso e fixo e ler a primeira linha de entrada, armazenando esse valor como N, iniciamos um loop de 1 até N para ler todos os valores da sequência da 2º linha de entrada e salvá-los em uma posição do vetor de acordo com a sua posição na sequência. Depois, definimos uma soma "padrão", denominada soma, a partir do 1º e do último elementos da sequência, que deverá ser a mesma para os demais pares. Depois, passamos por todo o vetor A novamente, posição por posição, para analisar cada par, sendo que se a soma do 1º número do par e seu oposto forem diferentes de soma, imprimi-se "N" e a programação é encerrada. Caso todas as somas respeitem a condição, imprimi-se "S" e o programa encerra.

É importante fazer duas observações para este problema:

  1. Para analisar um par, verificamos o valor da posição i no vetor A e o valor da posição N-i+1, pois isso serve para todos os pares de uma sequência quando queremos analisar números "opostos". Por exemplo, sabemos que o 2º número é oposto ao penúltimo número, então se N=10, devemos analisar o valor de A[2] e o valor de A[9] (10-2+1=9);
  2. É de extrema importância analisar o valor máximo de N, já que a complexidade do problema é O(N). Nesse caso não devemos nos preocupar, pois N vai até 1000, mas em caso de números maiores como 10^8, poderíamos receber "Tempo Limite Excedido" e a lógica acima não passaria na submissão. Sugiro a leitura da nossa Aula Especial de Complexidade .

Complexidade: O(N).

Segue o código comentado para melhor compreensão da solução:


#include<bits/stdc++.h> //biblioteca utilizada
using namespace std;
const int MAXN=10001; //define o valor de 'MAXN' como 100001
int A[MAXN]; //define um vetor 'A' de tamanho 'MAXN'
int main()
{
int N; //declara 'N
scanf("%d", &N); //leitura da entrada
for(int i=1; i<=N; i++) //loop para ler toda a entrada
{
scanf("%d", &A[i]); //lê o valor e armazena no vetor 'A' com o índice da posição desse número na sequência dada
}
int soma=A[1]+A[N]; //define qual o valor da soma em que todos os valores "opostos" devem resultar quando somados
for(int i=1; i<=N; i++) //loop para verificar todos os pares de valores opostos
{
if(A[i]+A[N-i+1] != soma) //se a soma de um dos pares for diferente da "padrão" ('soma')
{
printf("N"); //imprimi N
return 0; //retorna a 0 (encerra)
}
}
printf("S"); //se todas as somas forem iguais a "padrão" ('soma'), imprimi S
return 0; //retorna a 0 (encerra)
}

view raw

Escher.cpp

hosted with ❤ by GitHub