Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

lucas _vinicius

exercício de laços

Recommended Posts

Olá pessoal,estou com um probleminha nesse exercício aqui:

 

"Fazer um programa para encontrar todos os pares de números amigáveis entre 1 e 100000. Um par de números é amigável[/size]

quando cada um deles é igual à soma dos divisores do outro."[/size]

 

Bem eu como nuca tinha me deparado com uma atividade dessas fiz assim:[/size]

#include <stdio.h>

int main ()
{
	
	long int x,z,y,y1;
	x=y=y1=0;
	
	for (y=0,x=0;x<=100000;x++)
	{
		
		for (z=0;z<x;z++)	if (x%z==0) y+=z;
		for (z=0;z<y;z++)	if (y%z==0) y1+=z;
		
		if (y==y1)	printf ("(%d %d) ",x,y);
		
	}
	
	return 0;
}
Obviamente o pc não consegue fazer a leitura de três laços for de 100000 um em seguida do outro ai da um treco(que eu axo que seria a falta de memoria talvez,ou o super uso dela forçando um subscrevimento na memoria << são apenas suposições),mas o fato é que não consigo pesar em um outro método para fazer esse exercício;Poderiam me ajudar?me dando pelo menos o raciocínio logico para faze-lo...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro detalhe que vc deve observar: a relação "número amigável" é simétrica. Isso significa que sendo o par (a,b) amigável, o par (b,a) também o é. Você pode utilizar isso e um memoize ( reduzir a quantidade de comparações.

 

Segundo: não me parece ser essa a definição de número amigável. http://mathworld.wolfram.com/FriendlyPair.html

http://en.wikipedia.org/wiki/Friendly_number

Repare que são números *distintos*, então (n,n) não entra na solução.

#include <stdio.h>
unsigned int get_divisors(unsigned int n, unsigned int * divisors) {
  unsigned int j=0;
 
  for(unsigned int i=n; i; i--) {
    if (n%i == 0) {
      divisors[j]=i;
      j++;
    }
  }
  return j;
}
 
float summation_ratio(unsigned int n) {
   unsigned int divisors[n];
   unsigned int sum = 0;
   unsigned int count_divisors = get_divisors(n, divisors);
   while(count_divisors) {
     sum += divisors[count_divisors-1];
     count_divisors--;
   }
   return (sum*1.0)/n;
}
 
int main(void) {
  unsigned int inicio, tmp_local;
  const unsigned int final = 200;
 
  for(inicio=1; inicio <= final; inicio++) {
    for(tmp_local=1; tmp_local <= final; tmp_local++) {
      if (summation_ratio(inicio) == summation_ratio(tmp_local) && inicio!=tmp_local) {
        printf("(%d,%d) ", inicio, tmp_local);
      }
    }
  }
  puts("");
  return 0;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bem _Isis_ observei atentamente os pontos que você destacou e corrigi meu programa:

#include <stdio.h>

int main ()
{
	
	long int x,z,s1,s2,t1=0;
	
	puts ("\tNumeros amigaveis\n\n");
	
	for (x=1;x<=100000;x++)
	{
		s1=s2=0;
		
		for (z=1;z<x;z++)	
			if (x%z==0) s1+=z;
		for (z=1;z<s1;z++)	
			if (s1%z==0) s2+=z;
		
		if (((x==s2)&&(x!=s1))&&((x!=t1)&&((s1-x)>0)))
		{
			printf ("\t%d \t| \t%d\n",x,s1)
			t1=s1;
		}
	}
	
	puts (".");
	getchar();
	
	return 0;
}

Eu não utilizei Funções por que o exercício era para treinar o raciocínio logico com laços,eu acho que está bom mas se tiver mais algum ponto a destacar pode falar...

 

Você ajudou bastante!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.