Cod sursă (job #240442)

Utilizator avatar alexandrustr alexandru strambei alexandrustr IP ascuns
Problemă Sqrt (clasele 9-10) Compilator cpp | 2,90 kb
Rundă Arhiva de probleme Status evaluat
Dată 13 mai 2016 12:02:01 Scor 100
#include <stdio.h>
#include <math.h>
#define MAX 4000
int x[MAX], rez[MAX], aux[MAX], ct[MAX], e[MAX], r[MAX], g[MAX], sol[MAX], nul[MAX];
inline void shift(int a[], int k){
    int i;
    for(i=a[0]+k; i>k; i--){
        a[i]=a[i-k];
    }
}
inline void copy(int a[], int b[]){
    int i;
    for(i=b[0]+1; i<=a[0]; i++){
        a[i]=0;
    }
    for(i=0; i<=b[0]; i++){
        a[i]=b[i];
    }
}
inline int maiMic(int a[], int b[]){
    int i=b[0];
    if(a[0]<b[0]){
        return 1;
    }
    if(a[0]>b[0]){
        return 2;
    }
    while((i>0)&&(a[i]==b[i])){
        i--;
    }
    if((i==0)||(a[i]<b[i])){
        return 1;
    }
    return 2;
}
inline void scadere(int a[], int b[]){
    int tr=0, i=1;
    while((i<=b[0])||(tr!=0)){
        a[i]-=b[i];
        a[i]+=tr;
        if(a[i]<0){
            tr=-1;
            a[i]+=10;
        }else{
            tr=0;
        }
        i++;
    }
    while((a[0]>0)&&(a[a[0]]==0)){
        a[0]--;
    }
}
inline void inmultire(int a[], int b[], int c[]){
    int i, j, tr=0;
    for(i=1; i<=a[0]; i++){
        a[i]=0;
    }
    a[0]=b[0]+c[0]-1;
    for(i=1; i<=b[0]; i++){
        for(j=1; j<=c[0]; j++){
            a[i+j-1]+=b[i]*c[j];
        }
    }
    for(i=1; i<=a[0]; i++){
        tr+=a[i];
        a[i]=tr%10;
        tr/=10;
    }
    while(tr>0){
        a[++a[0]]=tr%10;
        tr/=10;
    }
}
int main(){
    int n, i, c, pas;
    char ch;
    FILE *fin, *fout;
    fin=fopen("sqrt.in", "r");
    fout=fopen("sqrt.out", "w");
    ch=fgetc(fin);
    n=0;
    while(ch!='\n'){
        n++;
        ch=fgetc(fin);
    }
    fclose(fin);
    fin=fopen("sqrt.in", "r");
    if(n%2==1){
        ch=fgetc(fin);
        x[1]=ch-'0';
        x[0]=1;
        i=1;
    }else{
        ch=fgetc(fin);
        x[2]=ch-'0';
        ch=fgetc(fin);
        x[1]=ch-'0';
        x[0]=2;
        i=2;
    }
    rez[1]=sqrt(x[2]*10+x[1]);
    rez[0]=1;
    inmultire(aux, rez, rez);
    scadere(x, aux);
    ct[0]=2; ct[1]=0; ct[2]=2;
    while(i<n){
        ch=fgetc(fin);
        shift(x, 1);
        x[0]++;
        x[1]=ch-'0';
        ch=fgetc(fin);
        shift(x, 1);
        x[0]++;
        x[1]=ch-'0';
        i+=2;
        c=0;
        inmultire(aux, rez, ct);
        copy(sol, nul);
        for(pas=1<<3; pas!=0; pas>>=1){
            if(c+pas<10){
                copy(r, aux);
                r[1]=c+pas;
                e[0]=1; e[1]=c+pas;
                inmultire(g, r, e);
                if(maiMic(g, x)==1){
                    c+=pas;
                    copy(sol, g);
                }
            }
        }
        scadere(x, sol);
        shift(rez, 1);
        rez[0]++;
        rez[1]=c;
    }
    for(i=rez[0]; i>0; i--){
        fputc(rez[i]+'0', fout);
    }
    fputc('\n', fout);
    fclose(fin);
    fclose(fout);
    return 0;
}