Cod sursa(job #444144)

Utilizator SpiderManSimoiu Robert SpiderMan Data 19 aprilie 2010 16:06:17
Problema Numere 2 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.12 kb
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>

#define BASE 10000
#define LUNG 30
#define PRTF "%04d"


void print(int *a)
{
    int i = a[0];

    printf("%d", a[i]);

    while (-- i > 0)
        printf(PRTF, a[i]);
    printf("\n");
}


void set(int *A, int X)
{
    memset(A, 0, sizeof(int)*LUNG);
    A[0] = 0;
    while (X)
    {
        ++A[0];
        A[A[0]] = X % BASE;
        X /= BASE;
    }
}

void mul(int *A, int B)
{
    int i, t = 0;
    for (i = 1; i <= A[0] || t; i++, t /= BASE)
        A[i] = (t += A[i] * B) % BASE;
    A[0] = i - 1;
}

void div_2(int *a)
{
    int rest = 0;
    int i;

    for (i = a[0]; i > 0; -- i)
    {
        a[i] = rest*BASE+a[i];
        rest = a[i] % 2;
        a[i] /= 2;
    }

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

void add(int *a, int scalar)
{
    int i;

    for (i = 1; i <= a[0] && scalar != 0; ++ i)
    {
        scalar += a[i];
        a[i] = scalar % BASE;
        scalar /= BASE;
    }

    while (scalar)
    {
        a[i ++] = scalar % BASE;
        scalar /= BASE;
    }

    if (i > a[0])
        a[0] = i-1;
}

void dec(int *a)
{
    int i = 1;

    while (a[i] == 0)
        a[i ++] = BASE-1;
    a[i] --;

    if (i == a[0] && a[i] == 0)
        a[0] --;
}

inline int cmp(int *A, int *B)
{
    if (A[0] < B[0]) return -1;
    else if (A[0] > B[0]) return 1;
    for (int i = A[0]; i > 0; --i)
        if (A[i] < B[i]) return -1;
        else if (A[i] > B[i]) return 1;
    return 0;
}

void mul_(int *a, const int *b)
{
    int C[LUNG];
    int i;

    set(C, 0);

    for (i = 1; i <= a[0]; ++ i)
    {
        int j, t;

        t = 0;
        for (j = 1; j <= b[0]; ++ j)
        {
            t += C[i+j-1] + a[i]*b[j];
            C[i+j-1] = t % BASE;
            t /= BASE;
        }

        while (t != 0)
        {
            t += C[i+j-1];
            C[i+j-1] = t % BASE;
            t /= BASE;
        }
    }

    C[0] = LUNG-1;
    while (C[C[0]] == 0 && C[0] > 0)
        C[0] --;

    memcpy(a, C, sizeof(int)*LUNG);
    assert(a[0] < LUNG);
}

void add_(int *A, const int *B)
{
      int i, t = 0;
      for (i=1; i<=A[0] || i<=B[0] || t; i++, t/=BASE)
              A[i] = (t += A[i] + B[i]) % BASE;
      A[0] = i - 1;
}

void power(const int *a, int b, int *c)
{
    int i;

    set(c, 1);
    for (i = 0; i < b; ++ i)
        mul_(c, a);
}


int P[LUNG];
int T[LUNG];
int B;

int main()
{
    int *left = (int*) malloc(sizeof(int)*LUNG);
    int *right = (int*) malloc(sizeof(int)*LUNG);
    int *mid = (int*) malloc(sizeof(int)*LUNG);
    char ch;


    freopen("numere2.in", "rt", stdin);
    freopen("numere2.out", "wt", stdout);

    set(P, 0);
    while (scanf(" %c", &ch) == 1) //aici trebe lucrat ....
    {
        mul(P, 10);
        add(P, (int)(ch - '0'));
    }

    set(T, 1);
    B = 0;
    while (cmp(T, P) < 0)
    {
        mul(T, 2);
        B ++;
    }

    if (cmp(T, P) == 0)
    {
        printf("%d\n%d\n", 2, B);
        return 0;
    }

    B --;
    while (B > 0)
    {
        set(left, 2);

        set(right, 1);
        do
        {
            mul(right, 2);
            power(right, B, T);
        }
        while (cmp(T, P) < 0);

        while (cmp(left, right) <= 0)
        {
            int res;

            memcpy(mid, left, sizeof(int)*LUNG);
            add_(mid, right);
            div_2(mid);

            power(mid, B, T);
            res = cmp(T, P);

            if (res == 0)
            {
                print(mid);
                printf("%d\n", B);
                return 0;
            }

            if (res < 0)
            {
                int *temp = left;
                left = mid;
                mid = temp;
                add(left, 1);
            }
            else
            {
                int *temp = right;
                right = mid;
                mid = temp;
                dec(right);
            }
        }

        B --;
    }


    return 0;
}