OBI2014 Caderno de soluções Modalidade Programação • Nível 1, Fase 2 30 de agosto de 2014 Promoção: Patrocínio: Olimpíada Brasileira de Informática OBI2014 1 Loteria Para esse problema podemos manter um vetor aposta[] com 100 posições. Onde aposta[i] = 1, se apostamos na peça i; aposta[i] = 0, caso contrário. Ao ler os números sorteados x, basta checarmos se aposta[x] = 1. for(int i = 1 ; i < 100 ; i++) aposta[i] = 0; for(int i = 0 ; i < 6 ; i++) { scanf(" %d",&x); aposta[x] = 1; } int acertos = 0; for(int i = 0 ; i < 6 ; i++) { scanf(" %d",&x); if(aposta[x]) acertos++; } Dado o número de acertos basta imprimir o texto correspondente. Olimpíada Brasileira de Informática OBI2014 2 Sinuca Para resolver esse problema podemos simular a criação do triângulo linha a linha. Primeiro observamos que o número de linhas é igual ao número de colunas fornecida para a primeira linha. Portanto podemos criar uma matriz triangulo[][] de iguais dimensões. A cada linha o número de bolas é reduzido em um: A linha número 0 tem n bolas, a linha 1 tem n − 1, ..., a linha j tem n − j bolas. Por m, cada coluna depende apenas das duas colunas logo abaixo, portanto podemos expressar triangulo[i][j] em função de triangulo[i − 1][j] e triangulo[i − 1][j − 1]. for (int i = 1; i < n; i++) { for (int j = 0; j < n - i; j++) triangulo[i][j] = triangulo[i-1][j] * triangulo[i-1][j+1]; } Olimpíada Brasileira de Informática OBI2014 3 Passa Bolinha Esse também é um problema que requer simulação, mas é um pouco mais complicado. A idéia do problema é usar uma função recursiva que processa uma busca em profundidade (DFS). Primeiramente mantemos uma matriz mark[][] indicando quais são os alunos que estão com a bandeira abaixada. Nossa função recursiva dfs(int y, int x, int n) vai receber qual a posição (x, y) que estamos e qual a dimensão n do grid. Ao entrar na posição (x, y), marcamos esse aluno como bandeira levantada (mark[y][x] = true) e visitamos as quatro posições adjacentes. Para facilitar o código criamos dois vetores dy[] e dx[] que indica os quatro vizinhos (Norte, Leste, Sul e Oeste). Antes de visitar uma posição vizinha, primeiro vericamos se essa posição está dentro do tabuleiro, vericamos se está com a bandeira abaixado e ,por m, se a camiseta tem número maior que a atual. bbb dy[] = {0, 1, 0, -1}; int dx[] = {1, 0, -1, 0}; void dfs(int y, int x, int n) { result++; mark[y][x] = true; } for (int d = 0; d < 4; d++) { int y2 = y + dy[d], x2 = x + dx[d]; if (0 <= min(y2, x2) && max(y2, x2) < n && !mark[y2][x2] && val[y2][x2] >= val[y][x]) dfs(y2, x2, n); }