Cod sursa(job #918125)

Utilizator apopeid13Apopeid Alejandro apopeid13 Data 18 martie 2013 17:27:01
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
# include <cstdio>
# include <cstring>
 
using namespace std;
 
#define F "numere2.in"
#define G "numere2.out"
 
# define maxd  402
 
int p[maxd], a[3*maxd], b;
 
void readf()
{
    char buf[2*maxd];
    FILE *fin=fopen(F, "r");
    fgets(buf, maxd, fin);
     
    int i=0, to=strlen(buf)-1;
    for(i=to-1;i>=0; i--) p[++p[0]] = buf[i]-0x30;
}
 
void mul(int a[], int b[], int c[])
{
    int i, j, t;
     
    for (i=1; i<=a[0]; i++)
    {
        for (t=0, j=1; j <= b[0] || t; j++, t/=10)
            c[i+j-1] = ( t += c[i+j-1] + a[i] * b[j] ) % 10;
        if ( i+j-2 > c[0] ) c[0] = i+j-2;
    }
}
 
void add(int to[], int a[], int b[])
{
    int i, t=0;
     
    for (i=1; i<=a[0] || i<=b[0] || t; i++, t/=10)
        to[ i ] = ( t += (a[i]+b[i]) ) % 10;
    to[ 0 ] = i-1;
}
 
void div(int a[], int b)
{
    int i, t=0;
     
    for (i=a[0]; i>0; i--, t %= b)
        a[i] = ( t = t*10 + a[i] ) / b;
    for (; a[0] > 1 && !a[a[0]]; a[0]--);
}
 
void sub(int a[], int b[])
{
    int i, t=0;
     
    for (i=1; i<=a[0]; i++)
        a[i] += ( t = ( a[i]-=(b[i]+t) ) < 0 ) * 10;
         
    for (; a[0] > 1 && ! a[ a[0] ]; a[0]--);
}
 
int cmp(int a[], int b[])
{
    if ( a[0]-b[0] ) return a[0]-b[0];
 
    for (int i=a[0]; i>=1; i--)
        if ( a[i]-b[i] ) return a[i]-b[i];
    return 0;  
}
 
void genn(int v[], int c)
{
    int i; for (v[0]=c, i=1; i<=c; i++) v[i] = 9;
}
 
void slowpow(int to[2*maxd], int a[2*maxd], int pw)
{
    int i, aux2[2*maxd];
     
    for (i=1; i<=pw; i++)
    {
        memset(aux2, 0, sizeof(aux2));
        mul(to, a, aux2);
        memcpy(to, aux2, sizeof(aux2));
    }
}
 
void solve()
{
    int _1[2*maxd];
    int pw, st[2*maxd], dr[2*maxd], mid[2*maxd];
    int max, min, auxp[2*maxd], rez;
 
    memset(_1, 0, sizeof(_1));
    _1[0] = _1[1] = 1;
     
    for (pw=100; pw>=1; pw--)
    {
        memset(st, 0, sizeof(st));
        memset(dr, 0, sizeof(dr));
        max = p[0] / pw + ( p[0] % pw != 0 );
        min = max > 2 ? max-2 : 1;
         
        st[ st[0]=min ] = 1;
        genn(dr, max);
         
        while ( cmp(st, dr) <= 0 )
        {
            memset(mid, 0, sizeof(mid));
            add(mid, st, dr);
            div(mid,  2);
             
            memset(auxp, 0, sizeof(auxp));
            auxp[0] = auxp[1] = 1;
            slowpow(auxp, mid, pw);
             
            rez = cmp(auxp, p);
             
            if ( ! rez )
                goto found_result;
             
            if ( rez < 0 )
            {
                memcpy(st, mid, sizeof(mid));
                add(st, st, _1);
            }
            if ( rez > 0 )
            {
                memcpy(dr, mid, sizeof(mid));
                sub(dr, _1);
            }
        }
    }
     
    memcpy(a, p, sizeof(p));
    b = 1;
     
    return;
     
    found_result :
     
    memcpy(a, mid, sizeof(mid));
    b = pw;
}
 
void writef()
{
    freopen(G, "w", stdout);
    int i;
     
    for (i=a[0]; i>=1; i--) printf("%d", a[i]);
    printf("\n%d\n", b);
}
 
int main()
{
    readf();
    solve();
    writef();
}