Cod sursa(job #485841)

Utilizator freak93Adrian Budau freak93 Data 19 septembrie 2010 18:00:26
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.06 kb
#include<cstdio>
#include<cstring>

using namespace std;

const char iname[]="numere2.in";
const char oname[]="numere2.out";
const int maxn=205;

char s[maxn];
int a[maxn],i,left[maxn],mid[maxn],right[maxn],x,rez;

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

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

void raise(int a[])
{
    for(int i=1,ok=1;ok;)
    {
        ++a[i];
        if(a[i]>=10000)
            a[i]-=10000;
        else
            ok=0;
    }
}

void sub(int a[])
{
    for(int i=1,ok=1;ok;)
    {
        --a[i];
        if(a[i]<0)
            a[i]+=10000;
        else
            ok=0;
    }
}

void mul(int A[], int B[])
{
      int i, j, t, C[maxn];
      memset(C, 0, sizeof(C));
      for (i = 1; i <= A[0]; i++)
      {
              for (t=0, j=1; j <= B[0] || t; j++, t/=10000)
                      C[i+j-1]=(t+=C[i+j-1]+A[i]*B[j])%10000;
              if (i + j - 2 > C[0]) C[0] = i + j - 2;
      }
      memcpy(A, C, sizeof(C));
}

void div(int A[], int B)
{
      int i, t = 0;
      for (i = A[0]; i > 0; i--, t %= B)
              A[i] = (t = t * 10000 + A[i]) / B;
      for (; A[0] > 1 && !A[A[0]]; A[0]--);
}

int check(int *base,int pow,int *rez)
{
    int aux[maxn];
    memset(aux,0,sizeof(aux));
    aux[0]=aux[1]=1;
    while(pow)
    {
        if(cmp(base,rez)==1)
            return 1;
        if(pow&1)
            mul(aux,base);
        if(cmp(aux,rez)==1)
            return 1;
        pow/=2;
        mul(base,base);
    }
    return cmp(aux,rez);
}

void afis(int a[])
{
    printf("%d",a[a[0]]);
    for(int i=a[0]-1;i;--i)
        printf("%04d",a[i]);
    printf("\n");
}

int main()
{
    freopen(iname,"r",stdin);
    freopen(oname,"w",stdout);
    fgets(s,sizeof(s),stdin);
    for(i=0;s[i]>='0'&&s[i]<='9';++i);
    for(--i;i>=0;i-=4)
    {
        a[++a[0]]=s[i]-'0';
        if(i>0)
            a[a[0]]+=(s[i-1]-'0')*10;
        if(i>1)
            a[a[0]]+=(s[i-2]-'0')*100;
        if(i>2)
            a[a[0]]+=(s[i-3]-'0')*1000;
    }
    for(i=156;i>1;--i)
    {
        memset(left,0,sizeof(left));
        memcpy(right,a,sizeof(a));
        left[0]=left[1]=1;
        while(cmp(left,right)<=0)
        {
            memset(mid,0,sizeof(mid));
            add(mid,left);
            add(mid,right);
            div(mid,2);
            x=check(mid,i,a);
            if(x==0)
            {
                rez=1;
                break;
            }
            if(x<0)
                add(left,right),div(left,2),raise(left);
            else
                add(right,left),div(right,2),sub(right);
        }
        if(rez)
            break;
    }
    memset(mid,0,sizeof(mid));
    add(mid,left);
    add(mid,right);
    div(mid,2);
    if(i==1)
        memcpy(mid,a,sizeof(a));
    afis(mid);
    printf("%d\n",i);
}