Solução dos Problemas da OBI2005

Agora que eu acho que todas as escolas já submeteram as soluções dos problemas da Programação Nível 1 da OBI desse ano, estou publicando minhas quatro soluções, em C.

Frota de Táxi

//Frota de Taxi - OBI2005
#include <stdio.h>

int main() {
	float a, g, ra, rg, al, ga;

	scanf("%f %f %f %f", &a, &g, &ra, &rg);
	al=a/ra;
	ga=g/rg;

	if (al<ga) {
		printf("A\n");
	} else {
		printf("G\n");
	}

	return 0;
}

Campo de Minhocas

//Campo de Minhocas - OBI2005
#include <stdio.h>
#define NMAX 102
#define NMAX 102

int main() {
	int n, m, soma, i, j, matriz[NMAX][NMAX], maior=0;

	scanf("%d %d", &n, &m);

	for (i=1; i<=n; i++) {
		for (j=1; j<=m; j++) {
			scanf("%d", &matriz[i][j]);
		}
	}

	for (i=1; i<=n; i++) {
		soma=0;
		for (j=1; j<=m; j++) {
			soma+=matriz[i][j];
		}
		if (soma>maior) {
			maior=soma;
		}
	}

	for (i=1; i<=m; i++) {
		soma=0;
		for (j=1; j<=n; j++) {
			soma+=matriz[j][i];
		}
		if (soma>maior) {
			maior=soma;
		}
	}

	printf("%d\n", maior);

	return 0;
}

Duende Perdido

//Duende Perdido - OBI2005
#include <stdio.h>
#include <values.h>
#define NMAX 102

int menor=MAXINT, p[NMAX][NMAX], custo[NMAX][NMAX];

int duende(int x, int y, int cus, int ox, int oy) {

	if (p[x][y]==1||p[x][y]==3) {
		if (cus<custo[x][y]) {
			custo[x][y]=cus;
			if ((x!=ox||y+1!=oy)&&p[x][y+1]!=-1) {
				duende(x, y+1, cus+1, x, y);
			}
			if ((x+1!=ox||y!=oy)&&p[x+1][y]!=-1) {
				duende(x+1, y, cus+1, x, y);
			}
			if ((x!=ox||y-1!=oy)&&p[x][y-1]!=-1) {
				duende(x, y-1, cus+1, x, y);
			}
			if ((x-1!=ox||y!=oy)&&p[x-1][y]!=-1) {
				duende(x-1, y, cus+1, x, y);
			}
		}
	}
	if (p[x][y]==0) {
		if (cus<custo[x][y]) {
			custo[x][y]=cus;
		}
		if (custo[x][y]<menor) {
			menor=custo[x][y];
		}
	}
}

int main() {
	int n, m, ix, iy, i, j;

	scanf("%d %d", &n, &m);

	for (i=0; i<=n+1; i++) {
		for (j=0; j<=m+1; j++) {
			p[i][j]=-1;
			custo[i][j]=MAXINT;
		}
	}

	for (i=1; i<=n; i++) {
		for (j=1; j<=m; j++) {
			scanf("%d", &p[i][j]);
			if (p[i][j]==3) {
				ix=i;
				iy=j;
			}
		}
	}

	duende(ix, iy, 0, 0, 0);

	printf("%d\n", menor);

	return 0;
}

Trilhas

//Trilhas - OBI2005
#include <stdio.h>
#include <values.h>
#define NMAX 102
#define MMAX 1001

int main() {
	int campeao, n, m[NMAX], a[NMAX][MMAX], saida=0, i, j, parou, subir[NMAX], descer[NMAX], menor=MAXINT;

	scanf("%d", &n);
	for (i=1; i<=n; i++) {
		scanf("%d", &m[i]);
		for (j=1; j<=m[i]; j++) {
			scanf("%d", &a[i][j]);
		}
	}

	//Primeiro vamos ver se precisa haver esforço de subida
	for (i=1; i<=n; i++) {
		parou=0;
		for (j=1; j<=m[i]; j++) {
			//printf("%d %d\n", i, j);
			if (a[i][j]>a[i][j+1]&&j!=m[i]) {
				parou=1;
				//printf("parou!\n");
				j=m[i];
			}
		}
		if (!parou) {
			//Então vamos parar por aí...
			printf("%d\n", i);
			return 0;
		}
	}

	//A mesma coisa ao contrário
	for (i=1; i<=n; i++) {
		parou=0;
		for (j=m[i]; j>=1; j--) {
			//printf("%d %d\n", i, j);
			if (a[i][j]>a[i][j-1]&&j!=1) {
				parou=1;
				//printf("parou!\n");
				j=1;
			}
		}
		if (!parou) {
			//Então vamos parar por aí...
			printf("%d\n", i);
			return 0;
		}
	}

	//Não deu...
	//Vamos contar quantos metros vamos ter que subir (ou descer=subir ao contrário)
	for (i=1; i<=n; i++) {
		descer[i]=0;
		subir[i]=0;
		for (j=1; j<=m[i]; j++) {
			if (a[i][j]>a[i][j+1]) {
				descer[i]+=(a[i][j]-a[i][j+1]);
			} else {
				subir[i]+=(a[i][j+1]-a[i][j]);
			}
		}
	}

	//E quem sobe ou desce menos?
	for (i=1; i<=n; i++) {
		if (subir[i]<menor) {
			menor=subir[i];
		}
		if (descer[i]<menor) {
			menor=descer[i];
		}
	}

	//Mas peraí... Temos que ver o primeiro na ordem de identificação!
	for (i=1; i<=n; i++) {
		if (subir[i]==menor||descer[i]==menor) {
			printf("%d\n", i);
			return 0;
		}
	}

	return 0;
}

O último deles (Trilhas) tá meio problemático. Tá fazendo um monte de coisa que não precisava… :S É que deu uns problemas lá na hora e eu tava cansado por causa do Duende e daí tive lag pra interpretar o enunciado e já que o tempo tava acabando por causa de problemas com o computador onde tava fazendo a prova eu fiz de uma maneira bem precária! Acho que ele tá com erros…

O do Duende é o mais interessante. Os outros dois não tiveram muita graça. O Trilhas também era bem fácil, mas inesperadamente o meu cérebro deu um Segmentation Fault quando fui fazer ele.

Gostaria que se alguém achasse algum erro em algum dos scripts me avisasse. O pessoal da OBI ainda não divulgou um gabarito pra testar os programas e nem o resultado. Acredito que semana que vem deve sair alguma coisa…

Desafios Lógicos e Sites

No Orkut, adicionei alguns caras que manjam de algoritmos, lógica, informática, Linux, ER, etc., como por exemplo Aurélio Marinho Jargas, Piter Punk (Roberto Freires Batista), Fábio Dias Moreira e Helder Suzuki. E com isso, pra minha felicidade total, recebi dois desafios lógicos! (destes últimos dois) :D

Permutação

O primeiro é sobre permutação. O Helder leu meu post sobre permutações e sugeriu a criação de um programa que, sem fazer as operações anteriores, determinasse o n-ésimo elemento de uma permutação. Ainda não fiz porque tô atolado de coisas pra fazer, mas pensei que posso descobrir cada letra a partir do seguinte…

Vou supôr que tenho uma cadeia ABC, tamanho=3, letras=3

As permutações seriam feitas na seguinte ordem:

  1. a a a
  2. a a b
  3. a a c
  4. a b a
  5. a b b
  6. a b c
  7. a c a
  8. a c b
  9. a c c
  10. b a a
  11. b a b
  12. b a c
  13. b b a
  14. b b b
  15. b b c
  16. b c a
  17. b c b
  18. b c c
  19. c a a
  20. c a b
  21. c a c
  22. c b a
  23. c b b
  24. c b c
  25. c c a
  26. c c b
  27. c c c

A primeira letra se alterna a cada 9 (3^2) vezes. A segunda a cada 3 (3^1). A terceira 1 (3^0). Portanto, eu acho que consigo descobrir cada uma das letras! Vamos supor que quero o décimo primeiro elemento.

11o. elemento

Está entre 10 e 18 – portanto a primeira letra é B

Está entre 10 e 12 – portanto a segunda letra é A

É 11 – A B C, A B C, A B C, A B!

BAB!

Sabendo disso fica fácil… Demorei pra pensar nisso, mas agora vou escrever o algoritmo, implementar e vencer o desafio! :)

Bom, e além do desafio, o Helder me falou uma coisa que eu achei muito legal! O vestibular do ITA só tem português, inglês, matemática, física e química. Ou seja, as matérias que mais precisaria estudar (biologia principalmente e história e geografia) não existem! emoticon Ultimamente, estive pensando em que universidade vou entrar. Estou na dúvida entre ITA e Unicamp, mas acho que prestarei vestibular para as duas.

MMC/MDC

O segundo desafio foi do Fábio Dias Moreira. Na verdade, não foi bem um desafio, foi uma idéia sobre o post do MMC.

E-mail dele

Eu li o seu post sobre cálculo de MMCs, e acho que você deveria tentar explorar as identidades a seguir:

  • mmc(x, y) * mdc(x, y) = x * y
  • mmc(mmc(x, y), z) = mmc(x, y, z)

Como calcular mdc é uma tarefa simples (já que mdc(x, y) = mdc(x, y % x)), que leva tempo O(log x), a conta mdc(x_1, x_2, …, x_n) deve levar tempo O(n log x).

Ainda não implementei tudo completamente, mas fiz alguns testes, que publiquei na seção de scripts.

Calcula o Máximo Divisor Comum (MDC) de vários termos

//MDC (Máximo Divisor Comum)
#include <stdio.h>
#include <values.h>

#define NMAX 101

int mdc(int *n, int tam) {
	int i, menor, desista, j;

	menor=MAXINT;
	for (i=0; i<tam; i++) {
		if (n[i]<menor) {
			menor=n[i];
		}
	}

	for (i=menor; i>=1; i--) {
		desista=0;
		for (j=0; j<tam; j++) {
			if (n[j]%i) {
				desista=1;
				j=tam;
			}
		}
		if (!desista) {
			return i;
		}
	}

}

int main() {
	int n[NMAX], tam, i;

	printf("Digite o número de termos: ");
	scanf("%d", &tam);
	for (i=0; i<tam; i++) {
		printf("%do. número: ", i+1);
		scanf("%d", &n[i]);
	}

	printf("MDC = %d\n", mdc(n,tam));
}

Calcula o Máximo Divisor Comum (MDC) entre 2 termos

//MDC (Máximo Divisor Comum) entre dois números
#include <stdio.h>

int mdc(int x, int y) {
	int i, menor;

	if (x<y) {
		menor=x;
	} else {
		menor=y;
	}

	for (i=menor; i>=1; i--) {
		if (!(x%i)&&!(y%i)) {
			return i;
		}
	}

	return 0;
}

int main() {
	int x, y;

	printf("Digite o primeiro número: ");
	scanf("%d", &x);
	printf("Digite o segundo número: ");
	scanf("%d", &y);

	printf("MDC ( %d , %d ) = %d\n", x, y, mdc(x,y));
}

Calcula o Mínimo Múltiplo Comum (MMC) entre 2 termos

//MMC - Mínimo Múltiplo Comum, para dois números

int mdc(int x, int y) {
	int i, menor;

	if (x<y) {
		menor=x;
	} else {
		menor=y;
	}

	for (i=menor; i>=1; i--) {
		if (!(x%i)&&!(y%i)) {
			return i;
		}
	}

	return 0;
}

int mmc(int x, int y) {
	return x*y/mdc(x,y);
}

int main() {
	int x, y;

	printf("Primeiro número: ");
	scanf("%d", &x);
	printf("Segundo número: ");
	scanf("%d", &y);

	printf("MMC (%d, %d): %d\n", x, y, mmc(x,y));
}

Tô chegando lá… Só falta fazer uma função que calcule o MMC dividindo em várias partes e fazendo vários MDCs. :p

Frações Egípcias

Bom, pra fazer eu pensar mais ainda, uma garota de 19 anos chamada Tatiane, que também leu o script do MMC, me enviou alguns e-mails sobre um algoritmo pra transformar frações próprias em frações egípcias. Só que o problema é que não pode usar funções, vetores, quase nada! Só pode usar os tipos char e int, e tem bastante regras que não deixam a pessoa sonhar muito. No fim, não consegui fazer, mas ela fez e parece que funcionou tudo certo. Em outro post, falarei mais sobre isso (depois que entender o algoritmo dela).

Meetweb

Hmmm… Uma empresa de construção de sites chamada MeetWeb me contratou pra programar para um site com um design já construído no Dreamwaver. Estou programando (PHP + Banco de dados MySql) e pretendo acabar em menos de 20 dias. Achei uma boa oferta, mesmo com uma pequena falta de tempo e o site exigir bastante coisinha de JavaScript (que eu não gosto muito - mas tô aproveitando pra aprender mais) e muita coisa repetida (o site é 100% administrável). É sempre bom pegar sites pra fazer, sempre acabo aprendendo mais alguma coisinha e um dinheirinho a mais sempre é bom também!

Site novo do Colégio

Esta semana comecei a fazer um site novo para o Colégio (o Salesiano, onde que eu estudo e trabalho), totalmente administrável também, com código válido e tableless, Flash… Uma coisa bem linda, leve e simples de administrar.

SOSPHP

Pra finalizar, o “meu” fórum, a SOSPHP tá com um movimento um pouco baixo e por isso tô fazendo um movimento para reanimá-lo. Então participem também! Entrem em www.sosphp.com.br e ajudem o fórum a crescer! Estou mandando mensagens para moderadores que estão sem visitar ultimamente, chamando mais gente e pedindo opiniões dos membros para melhorar o fórum (e é claro, pondo as opiniões em prática).

Algoritmo de Permutação e Expressões Regulares

permutar (dicionário Priberam)

permutar | v. tr. | v. tr. e int.

Conjugar

do Lat. permutare

v. tr.,

dar reciprocamente;

trocar uma coisa por outra;

cambiar;

v. tr. e int.,

trocar reciprocamente os lugares.

Em matemática, estuda-se a análise combinatória apenas no segundo ano do Ensino Médio (sinceramente, acho isso tão errado quanto não ensinarem a fórmula de Heron ao invés de b.h/2), mas por ser muito útil nas olimpíadas de matemática, acabei aprendendo antes. A permutação que o meu programa faz é com elementos repetidos. Dando a ele um limite de números (naturais) e o número de algarismos de cada saída, ele imprime todas as possibilidades na tela.

Permutação

#include <stdio .h>

#define NMAX 101 //Esta é uma constante que define o tamanho do vetor
#define NIVELMAX 5 //Esta constante define o número de níveis (número de caracteres numa permutação)
#define NUMEROS 2 //Esta constante define o número de números pelo qual a permutação passa.

int n[NMAX]; //Define o vetor "n" que contém os números pelo qual a permutação vai passando.

void permuta(int nivel) { //Inicia função que faz a permutação
        int i; //Define a variável i (contadora)

        if (nivel< =NIVELMAX) { //Se o nível for menor ou igual o nível
                for (i=1; i<=NUMEROS; i++) { //Laço para chamar uma função para cada valor diferente desse.
                        n[nivel]=i; //Define o número atual para i (o valor do laço)
                        permuta(nivel+1); //Chama a função (continua a recursão)
                } //Fim-para
        } else { //Senão
                //Imprime todas os números
                for (i=1; i<=NIVELMAX; i++) { //Laço para pegar os números de todas as funções
                        printf("%d", n[i]);
                } //Fim-para
                printf("n"); //Pula uma linha
        } //Fim-se
} //Fim da função

int main(void) { //Começa a função "main"
        int i; //Define a variável i (contadora)

        //Primeiro, zeramos o vetor "n" que contém os números que vão ser escritos.
        for (i=1; i<=NIVELMAX; i++) { //Laço
                n[i]=1;
        } //Fim-para

        //Chama a função com nível 1.
        permuta(1);
} //Fim-função

Esse código tá tão comentado que tá até difícil de entender…

O que você dá para o programa são as três constantes nas linhas 3, 4 e 5.

Gostei de fazer esse programa. Eu tive que pensar um pouco até na hora de escolher trabalhar com vetores, pois fazer permutações parece uma coisa mais simples mas é difícil. Fiz vários rascunhos de algoritmos no papel, mas aí só tá implementado em C. (eu nunca digito meus algoritmos… :blink: )

Comecei a estudar mais expressões regulares (para desenvolver um novo sistema de bbcodes e sintaxe colorida) e estou achando super legal. É um pouco complicado, mas tem muita lógica e tem muitas coisas úteis que dá pra fazer com elas, principalmente na construção de sites interativos em PHP. Estou lendo o livro do Aurélio que está disponível em guia-er.sourceforge.net. É muito bom! :)

Esse cara é um pouco maluco, mas o que ele faz com expressões regulares é muito legal! Desde setembro/2004, eu utilizo um programa em Bash dele chamado Funções ZZ. As funções ZZ são vários aplicativos simples que utilizam expressões regulares para facilitar tarefas do dia-a-dia. Por exemplo, o conceito de permutação que eu utilizei acima foi de um dicionário on-line das funções ZZ.

Consultando as estatísticas hoje, fiquei feliz ao ver meu blog citado em projetando.blogspot.com. Nunca sei se meus textos estão sendo compreendidos e por isso acho legal quando vejo que alguém linkou para meu site.

Demonstrações matemáticas, IE 7, Bash, GeSHi

Ultimamente não tenho me dedicado muito a resolução de problemas lógicos utilizando algoritmos e não tenho programado em C, mas andei estudando um pouco LaTeX e demonstrando teoremas matemáticos. Quarta-feira, o professor Vavá sugeriu ao nosso grupo de estudo da Olimpíada de Matemática provar 10 teoremas da matemática (entre eles, a fórmula de Bhaskara, o Teorema de Pitágoras, Relação Fundamental da Trigonometria, etc.) e estou tentando demonstrá-los com até q.e.d. no fim… :D

Bom, já que estava estudando LaTeX e o objetivo era provar de forma clara os teoremas, acabei transformando alguns em PDF.

  • Provar que, dentre todos os retângulos de perímetro constante, o de maior área é o quadrado
  • Provar, a partir de um quadrado de lado “a”, o famoso Teorema de Pitágoras.

Atualizado em 2012: esses arquivos — area-quadrilatero.pdf e teorema-pitagoras.pdf — foram perdidos no servidor.

O Ivo me falou sobre a fórmula de Bhaskara e eu consegui provar que o produto de dois números pares é necessariamente um número par (essa é totalmente ridícula). Tem duas propriedades logaritmicas que há algum tempo eu sabia demonstrar, mas agora não lembro. E algumas outras coisas que ainda não faço idéia de como provar…

Quarta-feira, antes do encontro de matemática, minha banda (Zibian) ensaiou (foi um ensaio totalmente precário, mas fazia tempo que a gente não ensaiava).

Sexta-feira (ontem), fui num dos melhores shows da minha vida. Yamandu Costa, Paulo Moura, Armandinho (pelo amor de Deus, não é o cara do reggae) e Robertinho Silva tocaram no CIC em Florianópolis interpretando obras de Tom Jobim em homenagem aos 10 anos desde a morte desse grande compositor. Foi muito bom. Os caras tocando música instrumental de primeira com as lindas músicas do Tom.

Ontem também li sobre um artigo na página do Bruno Torres falando sobre os developers do IE 7 implementando no novo navegador (se é que aquilo é digno de ser chamado de navegador) uma engine da Gecko (do Mozilla) modificada. “Um engenheiro da microsoft, do time que está trabalhando no desenvolvimento da nova versão de seu pseudo-browser do ícone azul, afirmou extra-oficialmente que ele e seus pares estão trabalhando em uma adaptação de um engine open-source de renderização HTML e CSS, o gecko (lagartixa em português, por isso comendo mosca), usado pelos navegadores mozilla e firefox, além do Netscape.” (trecho do artigo). É uma pena que depois tenha descoberto que se tratava apenas de uma brincadeira de primeiro de abril e o nome do engenheiro era “Adrem Resworb” que ao contrário fica “Browser Merda”.

Tenho criado alguns scripts em Bash para resolver grandes problemas (é incrível a utilidade desses pequenos scripts!) e estou refazendo o QueimaCD, agora em dialog para o Sinapx (a distro que eu e um grupo de pessoas estamos desenvolvendo no SOSPHP).

Andei testando o GeSHi (é um syntax highlighter – um programinha pra deixar os códigos coloridos na página) e estou pensando em colocar aqui na página (mesmo antes de trocar de site, porque aquele novo design tava muito apagado e por isso, vou deixar a página assim mesmo até ter uma idéia melhor). É legal ele ter opções de várias linguagens e fica bonitinho… :)

Nos últimos dias, também li alguns trechos do “Algoritmos: Teoria e Prática”. Esse livro é bem complicadinho… No fim, tem 70 páginas (da 820 a 890) somente falando sobre propriedades das somatórias! Mas é totalmente bem explicado e tem muito conteúdo. Acho que foi uma ótima coisa ter comprado ele. Acho que o custo-benefício dele tá ótimo.

Hoje configurei o Slackware inteiro do Héliton via SSH (ainda bem que a internet tava boa nos dois lados), toquei um pouco de pandeiro (oO, tô quase igual o Robertinho Silva…), respondi alguma coisa em fóruns, ouvi música, assisti televisão… No fim, fiquei cheio de trabalho de escola pra fazer amanhã.

Bom… Mês que vem é a prova da OBI, o Papa morreu (90000 pessoas no Vaticano!? Alguém quer tentar calcular a densidade demográfica?), houve uma chacina totalmente cruel na Baixada Fluminense, assassinaram a Terri nos EUA… Acontece tanta coisa no mundo! :blink:

Função para MMC e Gerador de Gráficos em Setores

Baseando-me no programa KBruch (um joguinho educativo do KDE que serve pra somar e subtrair duas frações) resolvi fazer uma função que calculasse MMC (pra dar o resultado do KBruch bem rápido! Hehehe). A função recebe dois argumentos: o número de termos e os termos (num vetor) e ficou bem simpes (e eu até comentei). Vejam:

//Função para calcular o MMC

#include <stdio.h>

int mmc(int *num, int ntermos) {
	int i, maior=0, a, j, c;

	//Descobrindo o maior número
	for (i=0; i<ntermos; i++) {
		if (num[i]>maior) {
			maior=num[i];
		}
	}

	for (i=1; c!=1; i++) {
		c=1;
		a=maior*i;
		//Verificando se o maior número vezes o i atual é divisível por todos números do conjunto
		for (j=0; j<ntermos; j++) {
			if (a%num[j]) {
				c=0;
			}
		}
	}

	return maior*(i-1); //Retornando resultado
}

int main() {
	int n[1001], nt, i;

	//Recebe número de termos
	printf("Quantos termos? ");
	scanf("%d", &nt);

	//Recebe números
	for (i=0; i<nt; i++) {
		printf("%d: ", i+1);
		scanf("%d", &n[i]);
	}

	//Chama a função e imprime o resultado
	printf("\nResultado: %d\n", mmc(n, nt));

	return 0;
}

Depois eu fiquei pensando que eu não estou calculando MMC como as pessoas calculam, então depois vou desenvolver uma outra função que calcule o MMC como as pessoas geralmente fazem, tipo assim:

MMC como as pessoas fazem

  • 4, 5 | 2
  • 2, 5 | 2
  • 1, 5 | 5
  • 1, 1 | /
  • 2 . 2 . 5 = 20

[update] Já criei esse programa agora:

//MMC do jeito que as pessoas tiram geralmente

#include <stdio.h>
int res[10000], co=0;

int mmc(int *n, int nt) {
	int i, k, dv, at;

	for (i=0; i<nt-1; i++) {
		printf("%d, ", n[i]);
	}
	printf("%d | ", n[nt-1]);

	dv=0;
	for (i=2; !dv&&at!=nt; i++) {
		dv=0;
		at=0;
		for (k=0; k<nt; k++) {
			if (!(n[k]%i)) {
				dv=1;
				n[k]/=i;
			} else if (n[k]==1) {
				at+=1;
			}
		}
		if (dv) {
			printf("%d\n", i);
			res[co++]=i--;
		}
	}

	if (at==nt) {
		return 1;
	} else {
		return i*mmc(n, nt);
	}
}

int main(void) {
	int n[1001], nt, i, resultado;

	printf("MMC - Mínimo Múltiplo Comum\n");
	printf("http://tableless.tiagomadeira.net/script/mmc-comum.c\n\n");

	printf("Este programa calcula o MMC de vários termos inteiros que você especifica.\n");
	printf("Foi criado por Tiago Madeira usando um algoritmo semelhante ao que os professores\n");
	printf("de matemática ensinam nas escolas.\n\n");

	printf("De quantos números você quer calcular o MMC? ");
	scanf("%d", &nt);
	for (i=0; i<nt; i++) {
		printf("Digite o %d. número: ", i+1);
		scanf("%d", &n[i]);
	}
	printf("\n");

	printf("Para você calcular o MMC de vários termos, basta você ir dividindo eles por primos\n");
	printf("até todos se tornarem o número 1 (um). O programa faz isto exatamente como você\n");
	printf("faria. Acompanhe o cálculo abaixo:\n\n");

	resultado=mmc(n, nt);
	printf("X\n\n", resultado);
	for (i=0; i<co-1; i++) {
		printf("%d . ", res[i]);
	}
	printf("%d = %d\n", res[co-1], resultado);

	printf("Ou seja, o menor número que é divisível por todos os números que você colocou é\n");
	printf("este. Isto tem grandes utilidades e uma delas (talvez a mais utilizada) é fazer\n");
	printf("cálculos com frações de denominadores diferentes.\n\n");

	printf("Observação: Este cálculo é a maneira com que as pessoas costumam aprender, mas\n");
	printf("desenvolvi um outro programa que (além de falar menos) tem um custo menor\n");
	printf("(calcula de forma mais rápida). Ele está disponível em\n");
	printf("http://tableless.tiagomadeira.net/script/mmc.c\n");

	return 0;
}

[/update]

Mas meu programa faz assim:

MMC pelo meu programa

  • 4, 5 - qual o maior? 5.
  • 5*2 é múltiplo de 4? Não.
  • 5*3 é múltiplo de 4? Não.
  • 5*4 é múltiplo de 4? Sim.
  • MMC encontrado: 5*4=20.

Mas com dois termos é bem simples (tem uma função para dois termos no programa do KBruch). O legal é que a minha função funciona com o número de termos que eu quiser. Vou demonstrar como ela funciona para três termos.

MMC com três termos no meu programa

  • 4, 5, 6 - qual é o maior? 6.
  • 6*2 é múltiplo de 4? Sim. Segue. É múltiplo de 5? Não. Para.
  • 6*3 é múltiplo de 4? Não. Para tudo.
  • 6*4 é múltiplo de 4? Sim. Segue. É múltiplo de 5? Não. Para.
  • ...
  • 6*10 é múltiplo de 4? Sim. Segue. É múltiplo de 5? Sim.
  • MMC encontrado: 6*10=60.

Acho que fica mais simples de entender no método convencional mesmo…

Método convencional - MMC de três termos

  • 4, 5, 6 | 2
  • 2, 5, 3 | 2
  • 1, 5, 3 | 3
  • 1, 5, 1 | 5
  • 1, 1, 1 | /
  • 2 . 2 . 3 . 5 = 60

E por causa disso, desenvolvi um programa que calcula da forma tradicional o MMC. É uma função recursiva. Ele é bem didático e mostra todo o raciocínio e algumas observações, porém o seu custo é maior (é mais demorado) que o primeiro.

Bom, nas aulas de matemática, andei desenvolvendo uns scripts muito úteis pra não precisar ficar calculando muito. Fiz um que calcula juros compostos, mas não publiquei. O que eu publiquei foi o que você digita o rótulo e o valor de cada pedaço de um gráfico de setores e ele devolve o número de graus que cada um deve ter (é uma simples regra de três, mas mesmo assim fiz pra brincar mesmo). Veja:

//Gerador de Gráficos em Setores
#include <stdio.h>
#define NMAX 1001

int main() {
	int n, i;
	float valor[NMAX], vt;
	char rotulo[NMAX][50];

	printf("Qual o número de valores? ");
	scanf("%d", &n);

	vt=0;
	for (i=1; i<=n; i++) {
		printf("Rótulo (%2d): ", i);
		scanf("%s", rotulo[i]);
		printf("Valor  (%2d): ", i);
		scanf("%f", &valor[i]);
		vt+=valor[i];
	}

	printf("\nResultados:\n(graus que devem ser usados na confecção do gráfico)\n");
	for (i=1; i<=n; i++) {
		printf("%s: %.2f graus\n", rotulo[i], valor[i]*360/vt);
	}
}

Hmmm… Tirei um 5,8 em biologia numa prova sobre biomas (minha menor nota em três anos) :blink: e errei uma questão numa prova de física, justamente aquilo que eu tinha feito um programa, a força gravitacional. Eu esqueci de elevar a notação científica da distância ao quadrado e com isto, meu resultado na prova foi 1,27 . 10^22 ao invés de 1,27 . 10^32. Mas tudo bem…

© 2005–2020 Tiago Madeira