Algoritmos Computacionais

Artigos sobre lógica de programação por Tiago Madeira

algoritmo: do Lat. algorithmos < Ár. alkharizmi: [Inform.] conjunto de etapas bem definidas necessárias para chegar à resolução de um problema.

Archive for the 'Ordenação' Category

Conclusão sobre Ordenação

Monday, January 16th, 2006

Resolvi resumir nosso estudo sobre algoritmos de ordenação, concluindo esta parte da Série Algoritmos sem explicar o Merge Sort, o Quick Sort e o Bubble Sort (três que eu estava pensando em explicar), mas apenas propondo que algoritmo de ordenação devemos usar para cada caso.

Não vou escrever o custo dos algoritmos de ordenação aqui porque seria uma perda inútil e esse material já pode ser encontrado em vários lugares (na Wikipedia, por exemplo).

Bom... Existem algoritmos de ordenação de vetores bem complexos. Você poderia aprender uma coisa super rápida, mas não vale a pena. Depois de resolver vários problemas que resolvem a ordenação, um professor na UNICAMP (não lembro quem foi) disse:

Não perca tempo com algoritmos de ordenação. Se você programa em C, use qsort; se programa em Pascal ou outra linguagem que não tenha Quicksort implementado, implementa rápido um Insertion Sort.

... e acho que ele estava certo. Talvez para usar em um grande projeto isso não seja o mais indicado, mas para competições não há como fazer melhor. No meio de um algoritmo complexo de fluxo de grafos, por exemplo, eu não tenho tempo para implementar um Quick Sort ou um outro algoritmo de ordenação complexo. Não devemos nos preocupar com isso... Então, usemos algoritmos que tenham implementação fácil, como o Insertion Sort e o Selection Sort. Já que o Insertion Sort tem um custo melhor (LaTeX: \Theta{}(n) no melhor caso), utilizemos ele.

Então pra que servem os outros?

Isso já discutimos na introdução sobre Ordenação: Basicamente, servem para estudar. O problema de ordenação é um programa muito interessante... ;) Mas aliás, foi pra não desanimar vocês dizendo que não tem muita utilidade prática que resolvi cortar os algoritmos de ordenação por aqui...

E como se usa o qsort() no C?

QSORT(3)                   Linux Programmer's Manual                  QSORT(3)

NAME
       qsort - sorts an array

SYNOPSIS
       #include <stdlib.h>

       void qsort(void *base, size_t nmemb, size_t size,
                  int(*compar)(const void *, const void *));

Com certeza não é uma das funções mais fáceis de usar... Hehehe... Aliás, confesso que tive alguma dificuldade antes de entender o que isso quer dizer.

Mas é o seguinte... Por o C ser super flexível, você pode criar uma função para comparar dois números. O Qsort exige isto no seu terceiro parâmetro e eu posso fazer o tipo de comparação que eu quiser: ver qual o maior, ver qual o menor ou ver qual tem o fator mínimo maior. Hehehe... É super interessante, mas geralmente não é tão útil, como nesse caso em que só queremos ordenar o vetor de menor pra maior. Então vamos fazer uma função que simplesmente compare dois e diga qual o maior.

O Qsort interpretará o retorno da nossa função da seguinte maneira:

  • Se quisermos colocar o primeiro argumento da nossa função antes do segundo em nosso vetor resultante, devemos retornar um número menor que zero.
  • Se quisermos colocar o segundo argumento da nossa função antes do primeiro em nosso vetor resultante, devemos retornar um número maior que zero.
  • Se retornarmos 0, ele vai colocar em qualquer ordem.

Portanto,

int compara(int *x, int *y) {
if (*x > *y) {
return 1;
}
if (*y > *x) {
return -1;
}
return 0;
}

Bom... Já que não precisamos retornar só 1 e -1, mas sim números maiores que 0 ou menores que 0, poderíamos fazer assim:

int compara(int *x, int *y) {
return *x-*y;
}

Não é verdade?

Não. Essa seria a função mais simples, mas poderia nos causar problemas. Vamos supôr que tentássemos ordenar o LaTeX: 2^{x} e o LaTeX: -2^{x}, que são os números que o seu compilador chama de maior e menor inteiro, respectivamente. ;) Aí ele subtrairia do primeiro o segundo e ia chegar a que número? Ninguém sabe. O programa iria buggar, ele poderia retornar qualquer coisa. Hehehe... Por isso, sempre usemos a de cima e não essa que eu acabei de fazer com a subtração! :D

E se quiséssemos ordenar de maior pra menor?

int compara(int *x, int *y) {
if (*x < *y) {
return 1;
}
if (*y > *x) {
return -1;
}
return 0;
}

:D Sentiram a flexibilidade da minha linguagem?

Bom... Agora vamos entender os outros argumentos do qsort() (esses são fáceis).

O primeiro argumento é o tão esperado vetor (na verdade, um ponteiro pra ele ;)). O segundo é o número de elementos no vetor. O terceiro é o tamanho que um elemento ocupa na memória.

#include <stdio.h>
#include <stdlib.h>
 
int compara(int *x, int *y) {
if (*x > *y) {
return 1;
}
if (*y > *x) {
return -1;
}
return 0;
}
 
int main() {
int i, vetor[]={53, 22, 55, 34, 1, 126, 72};
qsort(vetor, 7, sizeof(int), (void *)compara);
for (i=0; i<7; i++) {
printf("%d ", vetor[i]);
}
printf("n");
return 0;
}

Ah... Esse cast só serve para o GCC não mostrar um Warning (e passarmos o tipo correto pro QSort), mas acho que não faz diferença nenhuma, quer dizer, ele roda sem problemas sem ele.

E como se implementa um Insertion Sort em Pascal?

Isso já fizemos aqui. ;)

E se eu não concordar com nada disso?

Então comente!


Espero que tenham gostado da conclusão sobre algoritmos de ordenação. Queria reforçar que estou fazendo estes artigos baseando-me principalmente em olimpíadas e por isso sempre estou enfatizando problemas como o tempo de implementação e de execução. Para outras situações, temos vários caminhos diferentes para tomar. :)

Compare Preços de: notebooks, acer aspire, hp pavilion, computadores, pentium 4, nintendo wii, ps3, celulares, câmeras digitais

Mini-Poker

Friday, January 13th, 2006

Resolvi fazer uma pausa nos algoritmos de ordenação para mostrar como podemos usar os conhecimentos já adquiridos de maneira prática. Vamos neste artigo resolver o problema Mini-Poker, que caiu na prova da Programação Nível 2 (categoria para pessoas até 19 anos ou primeiro ano da faculdade) da Olimpíada Brasileira de Informática de 2005.

Esse post ficou gigante, mas é muito simples. Leia com atenção e acho que você não terá problemas... ;)

Objetivos

Com esta resolução de problema, espero treinar com vocês o conceito de:

  • Interpretação do Probema
  • Entrada e Saída
  • Ordenação por Inserção
  • Pseudocódigo

Acho que será legal para pôrmos em prática o que já estudamos sobre algoritmos.

O problema é bem simples, mas é só pra iniciar. Depois vamos resolvendo problemas cada vez mais difíceis... ;)

Enunciado

Mini-Poker é o nome do jogo de cartas que é uma simplificação de Poker, um dos mais famosos jogos de cartas do mundo. Mini-Poker é jogado com um baralho normal de 52 cartas, com quatro naipes (copas, paus, espadas e ouro), cada naipe compreendendo treze cartas (Ás, 2, 3, 4, 5, 6, 7, 8, 9, 10, Valete, Dama, Rei).

No início do jogo, cada jogador recebe cinco cartas. O conjunto de cinco cartas vale um certo número de pontos, de acordo com as regras descritas abaixo. Diferentemente do jogo de Poker normal, em Mini-poker o naipe das cartas é desconsiderado. Assim, para simplificar a descrição do jogo, vamos utilizar os números de 1 a 13 para identificar as cartas do baralho, na ordem dada acima. Uma outra diferença é que pode ocorrer empate entre mais de um vencedor; nesse caso os vencedores dividem o prêmio.

As regras para pontuação em Mini-Poker são as seguintes:

  1. Se as cinco cartas estão em seqüência a partir da carta LaTeX: x (ou seja, os valores das cartas são LaTeX: x, LaTeX: x+1, LaTeX: x+2, LaTeX: x+3 e LaTeX: x+4), a pontuação é LaTeX: x+200 pontos. Por exemplo, se as cartas recebidas são 10, 9, 8, 11 e 12, a pontuação é 208 pontos.
  2. Se há quatro cartas iguais LaTeX: x (uma quadra, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: x, LaTeX: x e LaTeX: y), a pontuação é LaTeX: x+180 pontos. Por exemplo, se as cartas recebidas são 1, 1, 1, 10 e 1, a pontuação é 181 pontos.
  3. Se há três cartas iguais LaTeX: x e outras duas cartas iguais LaTeX: y (uma trinca e um par, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: x, LaTeX: y e LaTeX: y), a pontuação é LaTeX: x+160 pontos. Por exemplo, se as cartas recebidas são 10, 4, 4, 10 e 4, a pontuação é 164 pontos.
  4. Se há três cartas iguais LaTeX: x e duas outras cartas diferentes LaTeX: y e LaTeX: z (uma trinca, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: x, LaTeX: y e LaTeX: z), a pontuação é LaTeX: x+140 pontos. Por exemplo, se as cartas recebidas são 2, 3, 2, 2 e 13, a pontuação é 142 pontos.
  5. Se há duas cartas iguais LaTeX: x, duas outras cartas iguais LaTeX: y (LaTeX: x \neq{} y) e uma outra carta distinta LaTeX: z (dois pares, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: y, LaTeX: y e LaTeX: z), a pontuação é LaTeX: 3 \times{} x + 2 \times{} y + 20 pontos, em que LaTeX: x > y. Por exemplo, se as cartas recebidas são 12, 7, 12, 8 e 7, a pontuação é 70 pontos.
  6. Se há apenas duas cartas iguais LaTeX: x e as outras são distintas (um par, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: y, LaTeX: z e LaTeX: t), a pontuação é LaTeX: x pontos. Por exemplo, se as cartas recebidas são 12, 13, 5, 8 e 13, a pontuação é 13 pontos.
  7. Se todas as cartas são distintas, não há pontuação.

Tarefa

Escreva um programa que, fornecidas as cartas dadas a um jogador, calcule a pontuação do jogador naquela jogada.

Entrada

A entrada é composta por vários casos de teste, cada um correspondendo a uma jogada. A primeira linha da entrada contém um número inteiro LaTeX: N que indica o número de casos de teste (LaTeX: 1 \leq{} N \leq{} 100). Cada uma das LaTeX: N linhas seguintes contém cinco números inteiros LaTeX: C_{1}, LaTeX: C_{2}, LaTeX: C_{3}, LaTeX: C_{4} e LaTeX: C_{5}, representando as cinco cartas recebidas por um jogador (LaTeX: 1 \leq{} C_{1}, C_{2}, C_{3}, C_{4}, C_{5} \leq{} 13).

A entrada deve ser lida do dispositivo de entrada padrão (normalmente o teclado).

Saída

Para cada caso de teste da entrada, seu programa deve produzir três linhas na saída. A primeira linha deve conter um identificador do caso de teste, no formato "Teste n", onde n é numerado seqüencialmente a partir de 1. A segunda linha deve conter a pontuação do jogador considerando as cinco cartas recebidas. A terceira linha deve ser deixada em branco. A grafia mostrada no Exemplo de Saída, abaixo, deve ser seguida rigorosamente.

A saída deve ser escrita no dispositivo de saída padrã (normalmente a tela).

Restrições

LaTeX: 1 \leq{} N \leq{} 100

LaTeX: 1 \leq{} C_{1}, C_{2}, C_{3}, C_{4}, C_{5} \leq{} 13

Exemplo de Entrada

2
12 3 10 3 12
1 2 3 5 4

Saída para o Exemplo de Entrada

Teste 1
62

Teste 2
201

Comentários sobre os problemas de olimpíadas

Todos os problemas passados em competições de programação tem um enunciado parecido com o desse. São especificados todos os limites (restrições), é dito exatamente como será a entrada e como deve ser a saída e geralmente tem uma historinha no começo... :D

Bom... Todos esses dados são fundamentais. Alguns limites nem vamos usar, não tem importância para a nossa solução, mas pode ter importância para outra pessoa que queira implementar um algoritmo diferente. A sintaxe da entrada e da saída são extremamente importantes. Na prova da Seletiva IOI do ano passado, eu quase perdi 60 pontos (6 casos de teste) na solução de um problema simples porque meu programa desprezava um espaço no início de uma frase quando imprimia uma saída. E mesmo a historinha do começo é fundamental. Ela sempre dá boas dicas e algumas vezes até ilustra o problema (às vezes a gente nem lê o enunciado e já sabe que é um problema de grafos!)

Mas vamos a solução deste problema...

Por onde começar?

Com o tempo você pode decidir fazer um caminho diferente, mas eu sugiro começar sempre pelo recebimento da entrada. Aliás, acho que isto é atípico, porque a maioria das pessoas prefere ler bastante o problema e desenvolver todo o algoritmo a mão antes de botar a mão na massa. Eu acho que depois que a gente recebe a entrada, fica bem mais fácil fazer o resto e a gente pode ir pensando enquanto a gente recebe a entrada! Então, depois que lemos o problema e já entendemos tudo o que ele quer, vamos fazer a entrada!

O problema fala que começa nos dando um número N que será o número de casos de teste que teremos que receber depois. Sem dificuldade podemos escrever o pseudocódigo a seguir:

recebe N
para nteste LaTeX: leftarrow{} 1 até N, faça
fim-para

Já chamo a variável que loopa como nteste, porque já li a saída do problema e sei que vou precisar imprimir o número de caad caso de teste... ;)

Aí o enunciado diz que Cada uma das LaTeX: N linhas seguintes contém cinco números inteiros LaTeX: C_{1}, LaTeX: C_{2}, LaTeX: C_{3}, LaTeX: C_{4} e LaTeX: C_{5}, representando as cinco cartas recebidas por um jogador (LaTeX: 1 \leq{} C_{1}, C_{2}, C_{3}, C_{4}, C_{5} \leq{} 13). Então, vamos receber os cinco números em cada iteração e colocá-los num vetor, é claro!

recebe N
para nteste LaTeX: leftarrow{} 1 até N, faça
	recebe LaTeX: C_{1}, C_{2}, C_{3}, C_{4}, C_{5}
fim-para

E a entrada está pronta.

Desenvolvimento

O programa se baseia em encontrarmos valores iguais nos elementos do vetor. O que podemos fazer para facilitar essa tarefa?

Isso mesmo: A ordenação! :D Se os elementos estiverem ordenados, ficará bem mais fácil para procurarmos quatro números iguais, porque eles não poderão ser qualquer uma das possibilidades, mas somente LaTeX: C_{1}, C_{2}, C_{3}, C_{4} ou LaTeX: C_{2}, C_{3}, C_{4}, C_{5}.

Aí que algoritmos devemos implementar para ordenar? Isso é uma conclusão que vamos chegar no final de nossa série, mas para este algoritmo não tem solução melhor que a Ordenação por Inserção. É um caso pequeno (n=5) e a Ordenação por Inserção é mais rápida que a por Seleção, porque o seu melhor caso é uma função linear. Então, vamos implementar o Insertion Sort no nosso algoritmo:

recebe N
para nteste LaTeX: leftarrow{} 1 até N, faça
	recebe LaTeX: C_{1}, C_{2}, C_{3}, C_{4}, C_{5}
	início da ordenação por inserção
	para j LaTeX: leftarrow{} 2 até 5
		elemento LaTeX: leftarrow{} LaTeX: C_{j}
		i LaTeX: leftarrow{} j-1
		enquanto i > 0 e LaTeX: C_{i} > elemento, faça
			LaTeX: C_{i+1} LaTeX: leftarrow{} LaTeX: C_{i}
			LaTeX: i LaTeX: leftarrow{} LaTeX: C_{i-1}
		fim-enquanto
		LaTeX: C_{i+1} LaTeX: leftarrow{} elemento
	fim-para
	fim da ordenação por inserção
fim-para

O bom desses algoritmos de ordenação é que sua lógica é muito simples e por isso é fácil decorá-los... Ao menos o Insertion Sort e o Selection Sort são algoritmos básicos que todo programador deve conhecer bem. Bom... Acredito que vocês não tenham tido dificuldade pra entender até aqui. A cor vermelha no pseudocódigo eu vou usar daqui pra frente para um comentário, que aliás, é uma excelente prática de boa programação.

O resto do problema precisa calcular quantos pontos o cara fez, baseado em suas cartas, agora já ordenadas. Para isto vamos criar uma função para testar vários se e retornar o resultado.

Eu poderia tirar os se aninhados, mas assim fica mais fácil a compreensão.

Como vamos ver com os pseudocódigos a seguir, é fácil testar cada uma das regras com o vetor ordenado:

Primeira Regra - Seqüência

Se as cinco cartas estão em seqüência a partir da carta LaTeX: x (ou seja, os valores das cartas são LaTeX: x, LaTeX: x+1, LaTeX: x+2, LaTeX: x+3 e LaTeX: x+4), a pontuação é LaTeX: x+200 pontos. Por exemplo, se as cartas recebidas são 10, 9, 8, 11 e 12, a pontuação é 208 pontos.

se LaTeX: C_{1} = C_{2}-1 e LaTeX: C_{2} = C_{3}-1 e LaTeX: C_{3}=C_{4}-1 e LaTeX: C_{4}=C_{5}-1, então
 	retorna LaTeX: C_{1}+200
fim-se

Segunda Regra - Quadra

Se há quatro cartas iguais LaTeX: x (uma quadra, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: x, LaTeX: x e LaTeX: y), a pontuação é LaTeX: x+180 pontos. Por exemplo, se as cartas recebidas são 1, 1, 1, 10 e 1, a pontuação é 181 pontos.

se LaTeX: C_{1} = C_{2} = C_{3} = C_{4} ou LaTeX: C_{2} = C_{3} = C_{4} = C_{5}, então
	retorna LaTeX: C_{2}+180
fim-se

Aqui retornamos LaTeX: C_{2} porque ele será sempre parte da quadra (ela começando em LaTeX: C_{1} ou LaTeX: C_{2}).

Terceira e Quarta Regra - Trinca

Se há três cartas iguais LaTeX: x e outras duas cartas iguais LaTeX: y (uma trinca e um par, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: x, LaTeX: y e LaTeX: y), a pontuação é LaTeX: x+160 pontos. Por exemplo, se as cartas recebidas são 10, 4, 4, 10 e 4, a pontuação é 164 pontos.

se LaTeX: C_{1} = C_{2} = C_{3} ou LaTeX: C_{2} = C_{3} = C_{4} ou LaTeX: C_{3} = C_{4} = C_{5}, então
	se ( LaTeX: C_{1} neq{} C_{3} e LaTeX: C_{1} = C_{2} ) ou ( LaTeX: C_{3} neq{} C_{5} e LaTeX: C_{4} = C_{5} ), então
		retorna LaTeX: C_{3}+160

Se há três cartas iguais LaTeX: x e duas outras cartas diferentes LaTeX: y e LaTeX: z (uma trinca, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: x, LaTeX: y e LaTeX: z), a pontuação é LaTeX: x+140 pontos. Por exemplo, se as cartas recebidas são 2, 3, 2, 2 e 13, a pontuação é 142 pontos.

	senão
		retorna LaTeX: C_{3} + 140
	fim-se
fim-se

Note que aqui retornamos LaTeX: C_{3} porque ele será sempre parte da trinca (o mesmo motivo que retornarmos LaTeX: C_{2} para a quadra).

Quinta Regra - Duas Duplas

Se há duas cartas iguais LaTeX: x, duas outras cartas iguais LaTeX: y (LaTeX: x \neq{} y) e uma outra carta distinta LaTeX: z (dois pares, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: y, LaTeX: y e LaTeX: z), a pontuação é LaTeX: 3 \times{} x + 2 \times{} y + 20 pontos, em que LaTeX: x > y. Por exemplo, se as cartas recebidas são 12, 7, 12, 8 e 7, a pontuação é 70 pontos.

se LaTeX: C_{1} = C_{2} ou LaTeX: C_{2} = C_{3}, então
	se LaTeX: C_{3} = C_{4} ou LaTeX: C_{4} = C_{5}, então
		retorna LaTeX: 3 times{} C_{4} + 2 times{} C_{2} +20
	fim-se
fim-se

LaTeX: C_{2} será sempre elemento da menor dupla e LaTeX: C_{4} será sempre elemento da maior dupla. Por isso usamos eles como LaTeX: y e LaTeX: x, respectivamente.

Sexta Regra - Dupla

Se há apenas duas cartas iguais LaTeX: x e as outras são distintas (um par, ou seja, os valores das cartas são LaTeX: x, LaTeX: x, LaTeX: y, LaTeX: z e LaTeX: t), a pontuação é LaTeX: x pontos. Por exemplo, se as cartas recebidas são 12, 13, 5, 8 e 13, a pontuação é 13 pontos.

se LaTeX: C_{1} = C_{2} ou LaTeX: C_{2} = C_{3}, então
	retorna LaTeX: C_{2}
senão se LaTeX: C_{3} = C_{4} ou LaTeX: C_{4} = C_{5},
então
	retorna LaTeX: C_{4}
fim-se

Separei em dois SEs porque senão não saberíamos que valor retornar.

Sétima Regra

Se todas as cartas são distintas, não há pontuação.

retorna 0

Função Inteira

Juntando todos os SEs, temos:

função pontua (C)

primeira regra
se LaTeX: C_{1} = C_{2}-1 e LaTeX: C_{2} = C_{3}-1 e LaTeX: C_{3}=C_{4}-1 e LaTeX: C_{4}=C_{5}-1, então
 	retorna LaTeX: C_{1}+200
fim-se

segunda regra
se LaTeX: C_{1} = C_{2} = C_{3} = C_{4} ou LaTeX: C_{2} = C_{3} = C_{4} = C_{5}, então
	retorna LaTeX: C_{2}+180
fim-se

terceira e quarta regra
se LaTeX: C_{1} = C_{2} = C_{3} ou LaTeX: C_{2} = C_{3} = C_{4} ou LaTeX: C_{3} = C_{4} = C_{5}, então
	se ( LaTeX: C_{1} neq{} C_{3} e LaTeX: C_{1} = C_{2} ) ou ( LaTeX: C_{3} neq{} C_{5} e LaTeX: C_{4} = C_{5} ), então
		retorna LaTeX: C_{3}+160
	senão
		retorna LaTeX: C_{3} + 140
	fim-se
fim-se

quinta regra
se LaTeX: C_{1} = C_{2} ou LaTeX: C_{2} = C_{3}, então
	se LaTeX: C_{3} = C_{4} ou LaTeX: C_{4} = C_{5}, então
		retorna LaTeX: 3 times{} C_{4} + 2 times{} C_{2} +20
	fim-se
fim-se

sexta regra
se LaTeX: C_{1} = C_{2} ou LaTeX: C_{2} = C_{3}, então
	retorna LaTeX: C_{2}
senão se LaTeX: C_{3} = C_{4} ou LaTeX: C_{4} = C_{5},
então
	retorna LaTeX: C_{4}
fim-se

sétima regra
retorna 0

fim-função

Já que a função retorna assim que encontra um resultado, não há risco de ocorrer nada errado (por exemplo, uma quadra é sempre uma trinca, que é sempre uma dupla). Agora basta colocarmos esta função no nosso código e adaptar para a saída ser igual a que o problema pede.

Saída

Para chegar a saída, basta fazermos o programa imprimir Teste nteste e depois o retorno da função pontua. Com isto, temos:

recebe N
para nteste LaTeX: leftarrow{} 1 até N, faça
	recebe LaTeX: C_{1}, C_{2}, C_{3}, C_{4}, C_{5}
	início da ordenação por inserção
	para j LaTeX: leftarrow{} 2 até 5
		elemento LaTeX: leftarrow{} LaTeX: C_{j}
		i LaTeX: leftarrow{} j-1
		enquanto i > 0 e LaTeX: C_{i} > elemento, faça
			LaTeX: C_{i+1} LaTeX: leftarrow{} LaTeX: C_{i}
			LaTeX: i LaTeX: leftarrow{} LaTeX: C_{i-1}
		fim-enquanto
		LaTeX: C_{i+1} LaTeX: leftarrow{} elemento
	fim-para
	fim da ordenação por inserção

	imprime "Teste "
	imprime linha testen
	imprime linha pontua(C)
	imprime linha
fim-para

Fiz essa saída assim pra se parecer com Pascal, mas para cada linguagem ela pode ser bem diferente... Vejamos dois exemplos...

C

printf("Teste %dn%dnn", nteste, pontua(C));

PHP

echo "Teste ".$nteste."n".pontua($C)."nn";

Programa Completo

função pontua (C)

primeira regra
se LaTeX: C_{1} = C_{2}-1 e LaTeX: C_{2} = C_{3}-1 e LaTeX: C_{3}=C_{4}-1 e LaTeX: C_{4}=C_{5}-1, então
 	retorna LaTeX: C_{1}+200
fim-se

segunda regra
se LaTeX: C_{1} = C_{2} = C_{3} = C_{4} ou LaTeX: C_{2} = C_{3} = C_{4} = C_{5}, então
	retorna LaTeX: C_{2}+180
fim-se

terceira e quarta regra
se LaTeX: C_{1} = C_{2} = C_{3} ou LaTeX: C_{2} = C_{3} = C_{4} ou LaTeX: C_{3} = C_{4} = C_{5}, então
	se ( LaTeX: C_{1} neq{} C_{3} e LaTeX: C_{1} = C_{2} ) ou ( LaTeX: C_{3} neq{} C_{5} e LaTeX: C_{4} = C_{5} ), então
		retorna LaTeX: C_{3}+160
	senão
		retorna LaTeX: C_{3} + 140
	fim-se
fim-se

quinta regra
se LaTeX: C_{1} = C_{2} ou LaTeX: C_{2} = C_{3}, então
	se LaTeX: C_{3} = C_{4} ou LaTeX: C_{4} = C_{5}, então
		retorna LaTeX: 3 times{} C_{4} + 2 times{} C_{2} +20
	fim-se
fim-se

sexta regra
se LaTeX: C_{1} = C_{2} ou LaTeX: C_{2} = C_{3}, então
	retorna LaTeX: C_{2}
senão se LaTeX: C_{3} = C_{4} ou LaTeX: C_{4} = C_{5},
então
	retorna LaTeX: C_{4}
fim-se

sétima regra
retorna 0

fim-função

recebe N
para nteste LaTeX: leftarrow{} 1 até N, faça
	recebe LaTeX: C_{1}, C_{2}, C_{3}, C_{4}, C_{5}
	início da ordenação por inserção
	para j LaTeX: leftarrow{} 2 até 5
		elemento LaTeX: leftarrow{} LaTeX: C_{j}
		i LaTeX: leftarrow{} j-1
		enquanto i > 0 e LaTeX: C_{i} > elemento, faça
			LaTeX: C_{i+1} LaTeX: leftarrow{} LaTeX: C_{i}
			LaTeX: i LaTeX: leftarrow{} LaTeX: C_{i-1}
		fim-enquanto
		LaTeX: C_{i+1} LaTeX: leftarrow{} elemento
	fim-para
	fim da ordenação por inserção

	imprime "Teste "
	imprime linha testen
	imprime linha pontua(C)
	imprime linha
fim-para

Comentários sobre o problema

Este problema é muito chato. É trivial, mas perdemos um tempo enorme escrevendo ses. Ninguém gosta de um problema como esse, mas quando cai numa olimpíada somos obrigados a resolver... hehehe... Mas, para a felicidade geral de todos, saibam que a maioria dos problemas de olimpíadas não são assim. Exigem mais lógica e menos código. Com o tempo, vamos pegando problemas mais difíceis. Espero só ter cumprido meu objetivo dando uma utilidade pra ordenação, entrada e saída e que vocês tenham entendido tudo.

Espero que tenham gostado da solução. Eu implementei este programa em C há seis meses e se você estiver interessado, sua solução está aqui: poker.c.

Sugiro que quem esteja aprendendo algoritmos com meus artigos e já saiba programar um pouquinho, resolva alguns problemas simples do site da OBI, que separei especialmente pra vocês! :D

O mais importante é a interpretação e o seu pensamento... Programar é fácil! :D

Qualquer dúvida, crítica ou sugestão; poste um comentário ou envie um e-mail!

Compare Preços de: notebooks, acer aspire, hp pavilion, computadores, pentium 4, nintendo wii, ps3, celulares, câmeras digitais

53 assinantes

Mais artigos

Comentários recentes

  • Matheus Eduardo Maura: Faço engenharia eletrica-eletronica( UNIRP SÃO JOSE DO RIO PRETO), e...
  • rafael: muito legal o artigo mas teria como resolver esse algoritmo nao consegui de jeito nenhum,...
  • Roger: Bom artigo. Podia atualizar esse site
  • Aline Celestrino Bento: o que É ALGORITMO=exemplo:35 :7 porque eu ñ sei ALINE
  • Claudio: eu gostaria de saber este algoritmo: faça um algoritmo que determine, para um digrafo,...
  • ingrid morgana gomes paes: que bacana que legau isso e emtesamte e legau para apremder mais a...
  • Filipe Névola: filipe.bico@hotmail. com
  • Filipe Névola: Boa noite, gostaria de saber se você tem alguma implementação de menor caminho...
  • Carlos Luiz Silva Meirelles: estou fazendo curso de informática gratuito patrocindo pelo estado....
  • Maria Regina de Queiroz: Olá Tiago, li os seus artigos e gostei muito, gostaria se possivel que...

Categorias

Escrevo também...

  • Tiago Madeira
    Site pessoal e blog do autor destes artigos
  • Mal Vicioso
    Blog sobre filosofia e sobre a hipocrisia da sociedade

Links

Sobre o design

Este design foi copiado do CSS Zen Garden e modificado com autorização de seu autor, Gunta Klavina.

Licença

Todo o conteúdo deste site (incluindo textos, imagens, arquivos de áudio e quaisquer outros trabalhos), exceto quando especificado o contrário, está licenciado por Tiago Madeira sob uma Licença Creative Commons.

HTML 4.01 gerado por WordPress em 0.750 segundos.