Cod sursa(job #1690303)

Utilizator CipiNisNisioi Ciprian CipiNis Data 14 aprilie 2016 22:55:12
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.58 kb
#include <fstream>
#include <cstring>
#include <iostream>
#include <cmath>

#define Lmax 1000
#define BAZA 10000

using namespace std;

class BigInteger{

    public: int n[Lmax];

    BigInteger(){

        memset ( n, 0, sizeof ( n ) );
    }

    inline void operator = ( BigInteger A ){

        memcpy ( n, A.n, sizeof ( A.n ) );
    }

    inline void operator = ( int A ){

        memset ( n, 0, sizeof ( n ) );

        for ( ; A > 0; A /= BAZA )
            n[ ++n[0] ] = A % BAZA;
    }

    inline BigInteger operator + ( BigInteger &A ) const {

        BigInteger B;

        int i, T = 0;

        for ( i = 1; i <= A.n[0] or i <= n[0] or T; ++i, T /= BAZA ) {

            B.n[i] = ( T += ( A.n[i] + n[i] ) ) % BAZA;
        }

        B.n[0] = i - 1;

        return B;
    }

    inline BigInteger operator * ( BigInteger &A ) const {

        BigInteger C;

        int i, j, T;

        for ( i = 1; i <= n[0]; ++i ) {

            for ( T = 0, j = 1; j <= A.n[0] or T; ++j, T /= BAZA ){

                C.n[i + j - 1] = ( T += ( C.n[i + j - 1] + n[i] * A.n[j] ) ) % BAZA;
            }

            if ( i + j - 2 > C.n[0] )
                C.n[0] = i + j - 2;
        }

        return C;
    }

    inline BigInteger operator / ( int B ) const {

        BigInteger A;

        memcpy ( A.n, n, sizeof ( n ) );

        int i, T = 0;

        for ( i = A.n[0]; i > 0; --i, T %= B ) {

            A.n[i] = ( T = T * BAZA + A.n[i] ) / B;
        }

        for ( ; A.n[0] > 1 and !A.n[ A.n[0] ]; --A.n[0] );

        return A;
    }

    inline bool operator < ( BigInteger &A ) const {

        if ( n[0] < A.n[0] )
            return true;

        if ( n[0] > A.n[0] )
            return false;

        for ( int i = n[0]; i > 0; --i ) {

            if ( n[i] < A.n[i] )
                return true;

            if ( n[i] > A.n[i] )
                return false;
        }

        return false;
    }

    inline bool operator == ( BigInteger &A ) const {

        if ( n[0] != A.n[0] )
            return false;

        for ( int i = 1; i <= n[0]; ++i ) {

            if ( n[i] != A.n[i] )
                return false;
        }

        return true;
    }

    friend ifstream& operator >> ( ifstream &f, BigInteger &A ) {

        char Number[Lmax];

        memset ( Number, 0, sizeof ( 0 ));

        f >> Number;

        int L = strlen ( Number );

        for ( int i = L - 1; i >= 0; i -= 4 ){

            A.n[ ++A.n[0] ] = Number[i] - '0';

            if ( i > 0 ) A.n[ A.n[0] ] += ( ( Number[i - 1]- '0' ) * 10 );
            if ( i > 1 ) A.n[ A.n[0] ] += ( ( Number[i - 2] - '0' ) * 100 );
            if ( i > 2 ) A.n[ A.n[0] ] += ( ( Number[i - 3] - '0' ) * 1000 );
        }

        return f;
    }

    friend ofstream& operator << ( ofstream &f, BigInteger &A ) {

        f<< A.n[ A.n[0] ];

        for ( int i = A.n[0] - 1; i > 0; --i ) {

            if ( A.n[i] == 0 ) {

                for ( int X = 1; X < BAZA; X *= 10 )
                    f << "0";

                continue;
            }

            for ( int X = A.n[i] * 10; X < BAZA; X *= 10 )
                f << "0";

            f << A.n[i];
        }

        return f;
    }
};

BigInteger P, S; int PUTERE;

inline int NrCifre( BigInteger A ){

    int s = 0;

    s += log10( A.n[A.n[0]] ) + 1;

    for (int i = A.n[0]-1; i > 0; --i ){

        if ( A.n[i] == 0 ) {

            for ( int X = 1; X < BAZA; X *= 10 )
                s++;

            continue;
        }

        for ( int X = A.n[i] * 10; X < BAZA; X *= 10 )
            s++;

        s += log10( A.n[i] ) + 1;
    }

    return s;
}

inline BigInteger FastExponentiation ( BigInteger A, int E ) {

    BigInteger R; R = 1;

    while ( E > 0 ) {

        if ( E & 1 )
            R = R * A,
            --E;
        else
            A = A * A ,
            E >>= 1;

        if ( P < A )
            return A;

        if ( P < R )
            return R;
    }

    return R;
}

inline BigInteger FastExponentiation2 ( BigInteger A, int E ){

    BigInteger R; R = 1;

    while ( E > 0 ) {

        if ( E & 1 )
            R = R * A,
            --E;
        else
            A = A * A ,
            E >>= 1;
    }

    return R;
}

inline int BinarySearch ( int E, int iteratii ) {

    BigInteger Left, Right, aux;

    int cif = NrCifre( P ) / E;

    if ( cif == 0 ){

        Left = 1;
        Right = 10;
    }

    if ( cif == 1 ){

        Left = 1;
        Right = 100;
    }

    if ( cif > 1 ){

        Left = 10;
        Right = 10;

        Left = FastExponentiation2( Left, cif - 1 );
        Right = FastExponentiation2( Right, cif + 1 );
    }

    while ( Left < Right or Left == Right ) {

        if( !iteratii )
            break;

        BigInteger Middle;

        Middle = ( Left + Right ) / 2;

        BigInteger res = FastExponentiation( Middle, E );

        if ( res == P ) {

            S = Middle;

            return 1;
        }

        if ( res < P )
            Left = Middle;
        else
            Right = Middle;

        iteratii--;
    }

    return 0;
}

void Solve(){

    ifstream fin ("numere2.in");
    ofstream fout ("numere2.out");

    fin >> P;

    int i;

    for ( i = 60; i >= 1; i-- ){

        if ( BinarySearch( i, 230 ) )
            break;
    }

    fout << S << "\n";
    fout << i << "\n";
}

int main(){

    Solve();

    return 0;
}