Cod sursa(job #831868)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 9 decembrie 2012 13:41:44
Problema Numere 2 Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.84 kb
#include<stdio.h>
#include<string.h>

using namespace std;

#define MAXF 205

typedef int Huge[ MAXF ];

int i, j, res_b, max_b, b;
char S[ MAXF ];
Huge N, res, a, aux, st, end, mid, dif, last, tmp, aux_mid;

inline void copy(Huge a, Huge b)
{
    for(int i = b[0] + 1; i <= a[0]; ++i)
        a[i] = 0;
    for(int i = 1; i <= b[0]; ++i)
        a[i] = b[i];
    a[0] = b[0];
}

inline int cmp(Huge a, Huge b)
{
    if(a[0] > b[0])
        return 1;
    else if(a[0] < b[0])
        return -1;

    for(i = a[0]; i; --i)
        if(a[i] > b[i])
            return 1;
        else if(a[i] < b[i])
            return -1;

    return 0;
}

inline void Add(Huge a, Huge b)
{
    int i, T = 0;

    if(b[0] > a[0])
    {
        for(i = a[0] + 1; i <= b[0]; ++i)
            a[i] = 0;
        a[0] = b[0];
    }

    for(i = 1; i <= a[0]; ++i)
        a[i] += b[i] + T, T = a[i] / 10, a[i] %= 10;
    while(T)
        ++a[0], a[ a[0] ] = T % 10, T /= 10;
}

inline void Substract(Huge a, Huge b)
{
    int i, T = 0;

    if(a[0] > b[0])
        for(i = b[0] + 1; i <= a[0]; ++i)
            b[i] = 0;

    for(i = 1; i <= a[0]; ++i)
    {
        a[i] -= (b[i] + T);
        if(a[i] < 0)
            a[i] += 10, T = 1;
        else T = 0;
    }

    while(!a[ a[0] ] && a[0] > 1)
        --a[0];
}

inline void Divide(Huge a, int x)
{
    int i, r = 0;

    for(i = a[0]; i; --i)
    {
        r = r * 10 + a[i];
        a[i] = r / x;
        r %= x;
    }

    while(!a[ a[0] ] && a[0] > 1)
        --a[0];
}

inline void MultHuge(Huge a, Huge b, Huge c)
{
    int i, j, T = 0;

    c[0] = a[0] + b[0] - 1;
    for(i = 1; i <= c[0]; ++i)
        c[i] = 0;

    for(i = 1; i <= a[0]; ++i)
        for(j = 1; j <= b[0]; ++j)
            c[i+j-1] += a[i] * b[j];

    for(i = 1; i <= c[0]; ++i)
        c[i] += T, T = c[i] / 10, c[i] %= 10;

    while(T)
        ++c[0], c[ c[0] ] = T % 10, T /= 10;
}

inline void Mult(Huge a, int x)
{
    int i, T = 0;

    for(i = 1; i <= a[0]; ++i)
        a[i] *= x, a[i] += T, T = a[i] / 10, a[i] %= 10;

    while(T)
        ++a[0], a[ a[0] ] = T % 10, T /= 10;
}

inline void Read()
{
    FILE *f = fopen("numere2.in", "r");

    fgets(S, 103, f);

    int len = strlen(S) - 2;
    N[0] = len + 1;

    for(i = len, j = 1; i >= 0; --i, ++j)
        N[j] = S[i] - '0';

    fclose(f);
}

inline void Exp(Huge a, int b, Huge res)
{
    res[0] = res[1] = 1;

    while(b)
    {
        if(b%2)
            MultHuge(res, a, tmp), copy(res, tmp);
        MultHuge(a, a, tmp), copy(a, tmp);
        b /= 2;
    }
}

inline void Solve()
{
    int t;

    aux[0] = aux[1] = 1;

    while(cmp(aux, N) <= 0)
    {
        Mult(aux, 2);
        ++max_b;
    }
    --max_b;
    res_b = 1, copy(res, N), copy(last, N);

    for(b = 2; b <= max_b; ++b)
    {
        memset(st, 0, sizeof(st));
        st[0] = st[1] = 1;
        copy(end, last);
        copy(dif, end);
        Substract(dif, st);

        while(dif[0] > 1 || dif[1] > 1)
        {
            copy(mid, st);
            Add(mid, end);
            Divide(mid, 2);
            copy(aux_mid, mid);

            Exp(aux_mid, b, aux);
            t = cmp(aux, N);

            if(t <= 0)
                copy(st, mid);
            else copy(end, mid);

            copy(dif, end);
            Substract(dif, st);
        }

        copy(last, st);
        Exp(st, b, aux);
        if(cmp(aux, N) == 0)
        {
            res_b = b;
            copy(res, last);
        }
    }
}

inline void Write()
{
    FILE *g = fopen("numere2.out", "w");

    for(i = res[0]; i; --i)
        fprintf(g, "%d", res[i]);
    fprintf(g, "\n%d\n", res_b);

    fclose(g);
}

int main()
{
    Read();
    Solve();
    Write();

    return 0;
}