Cod sursa(job #115097)

Utilizator ZeusCatalin Tiseanu Zeus Data 16 decembrie 2007 10:47:42
Problema Multiplu Scor 100
Compilator cpp Status done
Runda preONI 2008, Runda 2, Clasele 11-12 Marime 6.67 kb

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define LL long long
#define CLR(xx) memset( xx, 0, sizeof( xx ) ) 

#define node pair<int,string>

#define SUBMIT

#ifndef SUBMIT

void add( num & A, num B )
{
       int i, t = 0;  
       for (i=1; i<=A[0] || i<=B[0] || t; i++, t/=10)  
               A[i] = (t += A[i] + B[i]) % 10;  
       A[0] = i - 1;  
}

void tst()
{
     for( LL l = 2; l >= 0; l *= 2 )
     {
          int ok = 1; LL aux = l;
          while( aux && ok ) if( aux % 10 > 1 ) ok = 0;     
          if( ok ) cout << l << endl;
     } 
}

bool ok()
{
     if( Z[0] == 1 && Z[1] == 0 )
         return false;
     
     for( int i = 1; i <= Z[0]; ++i )
         if( Z[i] > 1 )
             return false;
     
     return true;     
}

void make_number( num & A, int x )
{
     CLR( A );
     
     while( x )
            A[ ++A[0] ] = x % 10,
            x /= 10;
}

void solve( int aa, int bb )
{
     A = aa, B = bb;    
     
     M = ( A * B ) / gcd( A, B );
    
     Z[0] = 1;
     make_number( rM, M );
    
     while( !ok() )
         add( Z, rM );  
    
     for( int i = Z[0]; i >= 1; i-- )
         printf("%d", Z[i] ); printf("\n"); 
}

void solve_by_M( int mm )
{
     M = mm;
    
     CLR( Z );
    
     Z[0] = 1;
     make_number( rM, M );
    
     while( !ok() )
         add( Z, rM );  
    
     for( int i = Z[0]; i >= 1; i-- )
         printf("%d", Z[i] ); printf("\n"); 
}

LL queue[1<<21];
node q[1<<21]; 

LL smarter_by_M( int mm )
{
     int l, r; 
     LL el;
                 
     CLR(used);
     M = mm;
     
     if( M == 1 )
         return 1;
         
     used[ 1 ] = 1; 

     for( queue[l=r=0] = 1; l <= r; l++ )
     {
          el = queue[l];
          
          if( el % M == 0 )
              return el;
          
          if( !used[ (el * 10) % M ] )
              used[ (el * 10) % M ] = 1,
              queue[++r] = el * 10;
          if( !used[ (el * 10 + 1) % M ] )
              used[ (el * 10 + 1) % M ] = 1,
              queue[++r] = el * 10 + 1;
     }
}

string final_by_M( int mm )
{
     int l, r, el; 
     string x;
     node n;
                 
     CLR(used);
     M = mm;
     
     if( M == 1 )
         return "1";
         
     used[ 1 ] = 1; 

     for( q[l=r=0] = make_pair( 1, "1" ) ; l <= r; l++ )
     {
          n = q[l];
          
          el = n.first, x = n.second;
          
          if( el % M == 0 )
              return x;
          
          if( !used[ (el * 10) % M ] )
              used[ (el * 10) % M ] = 1,
              q[++r] = make_pair( (el * 10)%M, x + "0" );
          if( !used[ (el * 10 + 1) % M ] )
              used[ (el * 10 + 1) % M ] = 1,
              q[++r] = make_pair( (el * 10 + 1)%M, x + "1" );
     }
}


int q1[1<<21], q2[1<<21]; 

int length_by_M( int mm )
{
     int l, r, el, len; 
                 
     CLR(used);
     M = mm;
     
     if( M == 1 )
         return 1;
         
     used[ 1 ] = 1; 

     for( q1[l=r=0] = 1, q2[l=r=0] = 1 ; l <= r; l++ )
     {    
          el = q1[l], len = q2[l];
         
          if( el % M == 0 )
              return len;
          
          if( !used[ (el * 10) % M ] )
              used[ (el * 10) % M ] = 1,
              q1[++r] = (el*10)%M, q2[r] = len + 1;
          if( !used[ (el * 10 + 1) % M ] )
              used[ (el * 10+1) % M ] = 1,
              q1[++r] = (el*10+1)%M, q2[r] = len + 1;
     }
}

void idea()
{
    for( int mm = 1; mm <= 100; mm++ )
    {
         printf("%d = ", mm );
         LL x = smarter_by_M( mm );      
         cout << x << endl;
         if( mm % 100000 == 0 )
             system("PAUSE");
    } 
}

void brute_idea()
{
    printf("brute\n"); 
     
    for( int mm = 1; mm <= 100; mm++ )
    {
         printf("%d = ", mm );
         solve_by_M( mm );      
         if( mm % 100000 == 0 )
             system("PAUSE");
    }  
} 

void cata_solve()
{
    string t; 
    int curent = 0; 
     
    for( int mm = 1900000; mm <= 2000000; mm++ )
    {
         printf("%d = ", mm );
         t = final_by_M( mm );   
         curent >?= t.size();
         cout << curent << endl;
         if( mm % 100000 == 0 )
             system("PAUSE");
    } 
}

void len_solve()
{
    int mine;
    int curent = 0; 
     
    for( int mm = 1999000; mm <= 2000000; mm++ )
    {
         printf("%d = ", mm );
         mine = length_by_M( mm );   
         curent >?= mine;
         cout << curent << endl;
         if( mm % 100000 == 0 )
             system("PAUSE");
    } 
}

void stupid()
{
/*
    for( int mm = 1999000; mm <= 2000000; mm++ )
    {
         printf("%d = ", mm );
         cout << jmen_solve( mm ) << endl;
         if( mm % 100000 == 0 )
             system("PAUSE");
    } 
*/    
    for( int mm = 1; mm <= 2000000; mm++ )
    {
         printf("%d = ", mm );
         cout << jmen_solve( mm ) << endl;
         if( mm % 100000 == 0 )
             system("PAUSE");
    }
}


#endif

int A, B, M, qq[1<<21], fr[1<<21];
char prec[1<<21];

int gcd( int a, int b )
{
    if( !b )
        return a;
        
    return gcd( b, a % b );    
}

string jmen_solve( int mm )
{
     int l, r, el, n1, n2; 
     string x;
                 
     CLR( fr );
     M = mm;
     
     prec[ 1 ] = 1;
     fr[ 1 ] = -1;      
     string aux[2]; aux[0] = "0", aux[1] = "1";
     
     for( qq[l=r=0] = 1 ; l <= r; l++ )
     {
          el = qq[l];

          if( el % M == 0 )
          {
              x = "";
              
              while( fr[el] != -1 )
                     x += aux[ prec[el] ],
                     el = fr[ el ];
              
              x += aux[1];
              
              reverse( x.begin(), x.end() );
              return x;    
          }
          
          n1 = (el * 10) % M, n2 = (el * 10 + 1) % M;
          
          if( !fr[ n1 ] )
              qq[++r] = n1, fr[ qq[r] ] = el, prec[ qq[r] ] = 0;
              
          if( !fr[ n2 ] )
              qq[++r] = n2, fr[ qq[r] ] = el, prec[ qq[r] ] = 1;
     }  
}

int main()
{
    freopen("multiplu.in", "r", stdin);
    freopen("multiplu.out", "w", stdout);
    
//    clock_t st, en;
    
//    st = clock();
    
    scanf("%d %d", &A, &B);
    printf("%s\n", jmen_solve( (A * B) / gcd( A, B ) ).c_str() );
    
//    en = clock();
    
//    printf("time = %0.4lf\n", 1.0 * ( en - st ) / CLOCKS_PER_SEC ); 
    
//    system("PAUSE");
    
    return 0;    
}