PDA

Ver la versión completa : numeros y programacion



luis esc
02/04/2009, 01:34
Hola,

pues os cuento este pequeño problemilla matematico, aunque se me ha pasado por la cabeza programarlo en C++.
Voy a poner el codigo y luego os cuento.



#include <iostream>
using namespace std;
#include <stdlib.h>
#include <math.h>
int main (void)
{
int c,r,s,p,u,t,m,q,w,x,j,k;
int l,i=0;
do
{
l=i;
j=0;
do
{
i=i/10;
j++;
}
while( i != 0);
p=l%10;
u=p*pow(10,j);
s=l/10;
r=u+s;
c=r*r;
t=c;
k=0;
do
{
c=c/10;
k++;
}
while( c != 0);
m=t/pow(10,k-1);
q=t-m*pow(10,k-1);
w=q*10;
x=w+m;
if ( x==l*l)
{
cout<<l<<endl;
}
i=l;
i++;
}
while (i!=0);
system("pause");
return 0;
}


Bueno el problemilla es el siguiente:

Sea A un numero entero positivo escrito en base 10, al que hay que hacerle las siguientes operaciones:

-Pasamos la ultima cifra al principio del número y obtenemos B.
-Hacemos el cuadrado de éste numero, C=B^2
- y D lo obtenemos al pasar la primera cifra de C al final del numero.

Ahora, si este numero final es el cuadrado del original, es decir, si D=A^2 entonces nos quedamos con A, sino, pues no.

Un ejemplo A=23 , B=32 , C=1024 , D=0241 que no es 23^2=529
Pero para A=21 , B=12 , C=144 , D=441=21^2

PROBLEMA:
Encuentra todos los numeros que cumplan lo anterior.

Seguro, que esto tendra su truco matematica y tal, de todas formas, aun no me he parado a pensarlo, he decidido primero programar esto.

Bueno, os cuento ahora cómo funciona mi programa:

El programa principal es un bucle do-while, a priori infinito, para que encuentre tantos numeros como ganas tenga de estar yo sentado frente al ordenador esperando(aunque si en el enunciado pone que encontremos "todos" los numeros, alomejor es porque son un conjunto finito).
Asi que, una vez iniciado el do-while, el primer numero es el cero, y luego al final va incrementandolo en uno, para que asi vaya probando con todos los numeros.

Cojamos un numero natural arbitrario y explico entonces qué hace el programa.

Primero cojo el numero "i" y me lo guardo en una variable "l", es decir l=i;

A continuacion, lo que hago es calcular cuantos digitos tiene el numero "i".
Para ello lo que hago es dividir "i" entre 10, luego el resultado de nuevo entre 10,...asi asi...,hasta que el numero sea cero( es decir, lo que estoy haciendo es una division entera, luego cada vez que divido el pc se queda con la parte entera del cociente).
Por cada iteracion, aumento el contador "j" en uno.

Ahora debo pasar la ultima cifra del numero al principio.

Para ello, cojo el numero y me quedo con el resto que da al dividirlo entre 10 (division entera).
Ese resto, es justamente la ultima cifra.
Ahora lo que hago es multiplicar ese ultimo numero por diez elevado al numero de digitos del numero, que antes habia calculado.
Ahora hago la division entera del numero entre 10, para quedarme justo con las primeras cifras excepto la ultima.
Entonces sumo el resultado de esta division a lo que habia obtenido anteriormente para obtener el numero con la ultima cifra al principio.

El numero resultante lo elevo al cuadrado.

De nuevo, calculo cuantas cifras tiene este ultimo numero con el metodo que habia dicho antes.

Ahora tengo que cojer la primera cifra de este numero y ponerla al final.

Para ello, cojo el numero y lo divido entre diez elevado a su numero de cifras menos uno (division entera) y el resultado es justo la primera cifra.
Ahora tengo que poner esa cifra al final.
Lo que hago es cojer el numero y restarle el producto de la primera cifra por diez elevado al numero de cifras menos uno para asi quedarme con las ultimas cifras excepto la primera. Ahora cojo este resultado y lo multiplico por diez y finalmente le sumo la primera cifra para asi obtener el numero con la primera cifra al final.

Ahora finalmente con un condicional if digo que si este ultimo numero es el cuadrado del numero de partida, entonces que muestre por pantalla el numero de partida, sino nada.

Finalmente, incremento en uno el numero de partida.

Y aqui acaba el programa.

Bueno, despues de este rollo que he contado, resulta que los primeros numeros son 0,1,2,3,...

El programa muestra el 0,1,2,3 y luego ya se pasa al 655360, cuando el 21 tambien funciona.

El programa compila y con eso no hay problemas, el algoritmo creo tambien que es correcto.

El unico problema que da es el casting de variables, es decir , las he puesto todas como "int" y eso esta mal, he hecho cambios con esto, poniendolas como "double", "float" algunas "int" otras "double"...en fin...y en funcion de cómo declare las variables el programa da numeros a lo bestia o solo da el cero.

Si que se que la funcion "pow" para calcular exponentes requiere variables tipo "double", ademas el compilador me lo dice.


En fin, a ver si se puede hacer algo, porque esto del casting de variables es importante.


Saludos y gracias

luis esc
08/04/2009, 21:52
Bueno, hablé con mi profe de infor y me ayudó a rediseñar un código mucho mejor.
Ahora, el programa consta de varias funciones, tres exactamente:

-La primera, se encarga de contar las cifras del número a probar.
-La segunda se encarga de pasar la ultima cifra al principio.
-La tercera se encarga de pasar la primera cifra al final.

Las variables las he declarado todas como "long long int", antes las ponía simplemente como "int" y sacaba menos números que funcionaran correctamente.

Los números que va sacando son:

1
21
221
2221
22221
222221
2222221

Ahora sí que parece que los números que funcionan siguen un patrón.
Lo que me extraña es que no saque el 2 y el 3, que también funcionan.

Bueno, el problema del algoritmo queda resuelto, ahora queda dar la explicación matemática (ver foro de matemáticas).

Saludos

PD: se me olvidaba poner el nuevo código:



#include <iostream>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
long long int contar_cifras (long long int n)
{
long long int cifras=0, numero=n;
while(numero > 0)
{
cifras++;
numero=numero/10;
}
return cifras;
}
long long int pasar_ultima_cifra_al_principio (long long int n)
{
long long int ultima_cifra, cte=1;
ultima_cifra = n%10;
n=n/10;
for ( int i=0 ; i < contar_cifras (n) ; i++ )
{
cte=cte*10;
}
n=n+cte;
return n;
}
long long int pasar_primera_cifra_al_final (long long int numero)
{
long long int cte=1,c=numero,resto, numero_final=0;
while(c >= 10)
{
resto = c%10;
c=c/10;
numero_final=numero_final + resto*cte;
cte=cte*10;
}
numero_final=10*numero_final+c;
return numero_final;
}
int main ()
{
long long int numero_a_probar=0,B,C,D;
while(true)
{
B = pasar_ultima_cifra_al_principio (numero_a_probar);
C = B*B;
D = pasar_primera_cifra_al_final (C);
if ((numero_a_probar)*(numero_a_probar) == D)
cout<<numero_a_probar<<endl;
numero_a_probar++;
}
system("pause");
return 0;
}