Ver Mensaje Individual
  #103 (permalink)  
Antiguo 11/12/2014, 05:38
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Petando la pila. Problemas y retos usando recursividad.

Otra posible solución al problema de los vampiros.

Visto que mi planteamiento inicial de hacer permutaciones era demasiado lento he cambiado el punto de vista.

Al final, visto lo visto, se parece un poco al resto de soluciones. En mi caso, para llevar el conteo de los dígitos compongo una máscara que me permite saber si los números comparten el mismo grupo de dígitos.

Código C++:
Ver original
  1. const int _factor[] = { (int)1e0, (int)1e1, (int)1e2,
  2.                         (int)1e3, (int)1e4, (int)1e5,
  3.                         (int)1e6, (int)1e7, (int)1e8,
  4.                         (int)1e9 };
  5.  
  6.  
  7. int Mask( int num )
  8. {
  9.   int digit = num % 10;
  10.  
  11.   if ( num >= 10 )
  12.     return _factor[ digit ] + Mask( num / 10 );
  13.   else
  14.     return _factor[ digit ];
  15. }
  16.  
  17. int es_vampiro( int num, int min, int max, int mask )
  18. {
  19.   if ( num % min == 0 )
  20.   {
  21.     int num2 = num / min;
  22.  
  23.     if ( min % 10 || num2 % 10 )
  24.     {
  25.       if ( Mask( min ) + Mask( num2 ) == mask )
  26.         return 1;
  27.     }
  28.   }
  29.  
  30.   if ( min < max )
  31.     return es_vampiro( num, min + 1, max, mask );
  32.  
  33.   return 0;
  34. }
  35.  
  36. int esVampiro( int num )
  37. {
  38.   int digits = log10( num ) + 1;
  39.  
  40.   if ( digits % 2 )
  41.     return 0;
  42.  
  43.   if ( !(num % 100) && !( num - num / _factor[ digits - 2 ] * _factor[ digits - 2 ] ) )
  44.     return 0;
  45.  
  46.   int mask = Mask( num );
  47.   int min = _factor[ digits / 2 - 1 ] + 1;
  48.   int max = sqrt( 1 + 4.0f * num ) / 2;
  49.  
  50.   return es_vampiro( num, min, max, mask );
  51. }
  52.  
  53. int main(int , char ** )
  54. {
  55.   int counter = 0;
  56.   for ( int i=10000000 ; i<=12000000 ; ++i )
  57.     counter += esVampiro( i );
  58.  
  59.   printf( "%d\n", counter );
  60. }