Cod sursa(job #330249)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 9 iulie 2009 11:46:17
Problema Nunta Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.25 kb
# include <stdio.h>

const long int BAZA=1000;
const long int MAXN=1000;

typedef struct NUMAR {long int len,v[MAXN+1];};
typedef NUMAR MATRICE[3][3];

MATRICE zero_mat,unu_mat,mat_sab;
NUMAR num_zero,num_unu,num_doi;
    
long int max(long int a, long int b)
{
     if (a>b) return a;
     return b;
}

void normalizeaza(NUMAR &c)
{
     long int i;
     for (i=1;i<=c.len;i++)
         {
         c.v[i+1]+=c.v[i]/BAZA;
         c.v[i]%=BAZA;
         }
     while (c.v[c.len+1])
           {
           c.len++;
           c.v[c.len+1]+=c.v[c.len]/BAZA;
           c.v[c.len]%=BAZA;
           }
}

void aduna(NUMAR &c, NUMAR &a, NUMAR &b)
     {
     c=num_zero;
     c.len=max(a.len,b.len);
     long int i;
     for (i=1;i<=c.len;i++)
         {
         c.v[i]+=a.v[i]+b.v[i];
         c.v[i+1]+=c.v[i]/BAZA;
         c.v[i]%=BAZA;
         }
     normalizeaza(c);
     }

void inmulteste(NUMAR &c, NUMAR &a, NUMAR &b)
{
      c=num_zero;
      c.len=a.len+b.len-1;
      long int i,j;
      for (i=1;i<=a.len;i++)
          for (j=1;j<=b.len;j++)
              c.v[i+j-1]+=a.v[i]*b.v[j];
      normalizeaza(c);
}

void produs(MATRICE &c, MATRICE a, MATRICE b)
{
        NUMAR s,t;
        inmulteste(s,a[1][1],b[1][1]);
        inmulteste(t,a[1][2],b[2][1]);
        aduna(c[1][1],s,t);
        inmulteste(s,a[1][1],b[1][2]);
        inmulteste(t,a[1][2],b[2][2]);
        aduna(c[1][2],s,t);
        inmulteste(s,a[2][1],b[1][1]);
        inmulteste(t,a[2][2],b[2][1]);
        aduna(c[2][1],s,t);
        inmulteste(s,a[2][1],b[1][2]);
        inmulteste(t,a[2][2],b[2][2]);
        aduna(c[2][2],s,t);
}

void set_one(MATRICE &c)
{
     c[1][1]=num_unu;
     c[1][2]=num_zero;
     c[2][1]=num_zero;
     c[2][2]=num_unu;
}

void set_zero(MATRICE &c)
{
     c[1][1]=num_zero;
     c[1][2]=num_zero;
     c[2][1]=num_zero;
     c[2][2]=num_zero;
}

void set_sab(MATRICE &c)
{
     c[1][1]=num_zero;
     c[1][2]=num_unu;
     c[2][1]=num_unu;
     c[2][2]=num_unu;
}
     
     
         
void putere(MATRICE &c, long int n)
{
        if (n==0) {set_one(c);return;}
        if (n==1) {set_sab(c);return;}
        MATRICE aux;
        putere(aux,n/2);
        if (n%2==0) produs(c,aux,aux);
        else 
             {
             MATRICE aux2;
             produs(aux2,aux,aux);
             produs(c,aux2,mat_sab);
             }
}

void scrie(FILE *g, NUMAR a)
{
     fprintf(g,"%ld",a.v[a.len]);
     long int i;
     for (i=a.len-1;i>=1;i--)
         fprintf(g,"%03ld",a.v[i]);
     fprintf(g,"\n");
}

int main()
{
    long int n;
    FILE *f=fopen("nunta.in","r");
    FILE *g=fopen("nunta.out","w");
    fscanf(f,"%ld",&n);
    fclose(f);
    num_zero.len=1;
    num_unu.len=1;num_unu.v[1]=1;
    num_doi.len=1;num_doi.v[1]=2;
    set_sab(mat_sab);
    if (n==1)
       {
       scrie(g,num_unu);
       fclose(g);
       return 0;
       }
    if (n==2)
       {
       scrie(g,num_doi);
       fclose(g);
       return 0;
       }
    MATRICE m;
    putere(m,n-1);
    NUMAR sol=num_zero,aux1,aux2;
    inmulteste(aux1,m[1][1],num_unu);
    inmulteste(aux2,m[1][2],num_doi);
    aduna(sol,aux1,aux2);
    scrie(g,sol);
    fclose(g);
    return 0;
}