Cod sursa(job #337397)

Utilizator GheorgheMihaiMihai Gheorghe GheorgheMihai Data 3 august 2009 15:42:10
Problema Numere 2 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>

#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 value)
{
	memset(a, 0x00, sizeof(int)*LUNG);
	while(value) {
		a[++a[0]]=value%BASE;
		value/=BASE;
	}
}

void mul(int *a, int scalar)
{
	int i,t=0;
    for(i=1;i<=a[0];++i) {
        t+=a[i]*scalar;
        a[i]=t%BASE;
        t/=BASE;
    }
    while(t) {
        a[i++]=t%BASE;
        t/=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]--;
}

int cmp(const int *a, const int *b)
{
    int i;
    if(a[0]!=b[0])
        return a[0]-b[0];
    for(i=a[0];i>=1;--i)
        if(a[i]!=b[i])
            return a[i]-b[i];
    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!=0;++i) {
        t+=a[i]+b[i];
        a[i]=t%BASE;
        t/=BASE;
    }
    if(i>a[0])
        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[LUNG];
    int right[LUNG];
    int mid[LUNG];
    char ch;
    freopen("numere2.in","r",stdin);
    freopen("numere2.out","w",stdout);
    set(P,0);
    while(scanf(" %c",&ch)==1) {
        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;
}