Arquivo

Posts Tagged ‘Maratona’

Provas da Primeira Fase da Maratona de Programação

quinta-feira, 01/03/2012 Deixe um comentário

Os enunciados das provas das primeiras fases da Maratona de Programação a partir de 2006 podem ser encontrados no links a seguir:

 

Maratona: Mário (do Armário)

quarta-feira, 24/11/2010 Deixe um comentário

Prova 2007/Primeira Fase/Problema D

Solução:

#include <stdio.h>
#include <stdlib.h>

int maximo (int x, int y) {
	if (x>y) return x;
	else return y;
}

int main () {
	int N, L;
	int armarios[100000];
	int melhor, i, j;
	
	scanf ("%d%d", &N, &L);
	while (N!=0 || L!=0) {
		
		for (i = 0; i < L; i++) scanf ("%d", &armarios[i]);
		
		melhor = 0;
		i = 0;
		j = 0;
		
		while (melhor < N && j < L) {
			if (armarios[j] < armarios[i] + N) {
				melhor = maximo (melhor, j-i + 1);
				j++;
			}
			else i++;
		}
		
		printf ("%d\n", N-melhor);

		scanf ("%d%d", &N, &L);
	}
	return 0;
}

Maratona: Rouba-Monte

quarta-feira, 24/11/2010 Deixe um comentário

2007/Primeira Fase/Problema B

Solução:

#include <stdio.h>
#include <stdlib.h>

int maximo (int *v, int n) {
	int i, m = v[0];
	
	for (i = 0; i < n; i++) 
		if (v[i] > m) m = v[i];

	return m;
}

void zeraVetor (int *v, int n) {
	int i;
	for (i = 0; i < n; i++) v[i] = 0;
}

int busca (int x, int *v, int n, int jogador) {
	int i;
	
	for (i = 0; i < jogador; i++) if (v[i] == x) return i;
	for (i = jogador+1; i < n; i++) if (v[i] == x) return i;
		
	return i;
}

int main () {
	int N, J;
	int i, j, jogador, carta, m, pos;
	int baralho[13]; // cartas de 1 a 13, vetor de 0 a 12
	int montes[20]; // jogadores de 2 a 20, vetor de 0 a 18
	int topos[20]; // jogadores de 2 a 20, vetor de 0 a 18
	
	scanf ("%d%d", &N, &J);
	while (N!=0 || J!=0) {
		zeraVetor (baralho, 13);
		zeraVetor (montes, J);
		zeraVetor (topos, J);

		jogador = 0;
		
		for (i = 0; i < N; i++) {
			scanf ("%d", &carta);
			
			if (baralho[carta-1] == 1) { // Achou a carta nos descartes
				montes[jogador] += 2;
				topos[jogador] = carta;
				baralho[carta-1] = 0;
			}
			else {
				pos = busca (carta, topos, J, jogador);
				if (pos < J) { // Achou a carta no topo do monte de outro jogador
					montes[jogador] += montes[pos] + 1;
					montes[pos] = 0;
					topos[jogador] = carta;
					topos[pos] = 0;
				}
				else {
					if (topos[jogador] == carta) { // Achou a carta no topo dele mesmo
						montes[jogador] += 1;
					}
					else {
						baralho[carta-1] = 1;
						jogador = (jogador + 1) % J;
					}
				}
			}
		}
		
		m = maximo (montes, J);


		printf ("%d ", m);
		for (i = 0; i < J; i++)
			if (montes[i] == m) printf ("%d ", i+1);
		printf ("\n");
		
		scanf ("%d%d", &N, &J);
	}
	
	return 0;
}

Maratona: Histórico de Comandos

sexta-feira, 12/11/2010 Deixe um comentário

Prova 2007/Primeira Fase/Problema E

Neste problema, foram armazenados

  • Um vetor armazenando o histórico de comandos.
  • O maior comando presente no histórico.
  • Um vetor com uma posição para cada possível comando (o tamanho do vetor é o maior comando lido do histórico).

A princípio, todas as posições do segundo vetor estão zeradas. A cada comando executado do histórico, armazena-se neste vetor a ordem em que ele foi executado.

Solução (O(N)):

#include <stdio.h>
#include <stdlib.h>

int maximo (int x, int y) {
	if (x>y) return x;
	else return y;
}

int main () {
   int N;
   int *numeros, *comandos;
   int maior, i, total;
 
   scanf("%d", &N);
   while (N != 0){
      comandos = (int*)malloc (N*sizeof (int));
      total = 0;
 
      for (i = 0; i < N; i++) {
         scanf ("%d", &comandos[i]);
         maior = maximo (comandos[i], maior);
      }
 
      numeros = (int *)calloc (maior, sizeof(int));
 
      for (i = 0; i < N; i++){
         if (numeros[comandos[i]-1] != 0 )
            total += (i + 1) - numeros[comandos[i]-1];
         else
            total += comandos[i] + i;
 
         numeros[comandos[i]-1] = i + 1;
      }
 
      printf ("%d\n", total);
      scanf ("%d", &N);
   }
 
   return 0;
}

Maratona: Desempilhando Caixas

sexta-feira, 12/11/2010 2 comentários

Prova 2007/Primeira Fase/Problema F

Neste problema, foram armazenados:

  • Um vetor contendo o número de caixas presentes em cada pilha.
  • A pilha em que se encontra a caixa 1.
  • A altura em que a caixa 1 se encontra em sua pilha.

O algoritmo é simples: Supondo que o inventário se encontra na pilha X, percorre-se as pilhas de X para a esquerda calculando a quantidade de caixas que seriam retiradas neste sentido (o algoritmo para se um pilha não possuir caixas na mesma altura que o inventário). Em seguida, executa-se o mesmo para as pilhas da direita. A resposta é o menor valor encontrado. O algoritmo é O(N), mas a própria leitura dos dados é O(N x P).

Solução:

#include <stdio.h>
#include <stdlib.h>

int minimo (int x, int y) {
    if (x<y) return x;
    else return y;
}

int main () {
    int N, P;
    int i, j, pilha, altura;
    int nesq, ndir, caixa;
    int *v;
    
    scanf ("%d%d", &N, &P);
    while (N!=0 || P!=0) {
        v = (int *)malloc (P*sizeof (int));
        
        for (i = 0; i < P; i++) {
            scanf ("%d", &v[i]);
            for (j = 0; j < v[i]; j++) {
                scanf ("%d", &caixa);
                if (caixa == 1) {
                    pilha = i;
                    altura = j+1;
                }
            }
        }
        
        nesq = v[pilha] - altura;    // quantas caixas estao acima do inventario
        for (i = pilha-1; i >= 0 && v[i] >= altura; i--)
            nesq += (v[i]-altura+1);        // quantas caixas seraos retirada nesta pilha
        
        ndir = v[pilha] - altura;    // quantas caixas estao acima do inventario
        for (i = pilha+1; i < P && v[i] >= altura; i++)
            ndir += (v[i]-altura+1);        // quantas caixas seraos retirada nesta pilha
        
        printf ("%d\n", minimo (nesq, ndir));
        
        free (v);
    
        scanf ("%d%d", &N, &P);
    }
    
    return 0;
}