Cod sursa(job #993939)

Utilizator sleepaholicNeculaescu Theodor sleepaholic Data 4 septembrie 2013 18:53:53
Problema Aliens Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.35 kb
#include<stdio.h>
#include<cmath>
#include<algorithm>

#define maxn 53
#define maxlog1 20
#define maxlog2 15
#define inf 31000
#define maxcif 500

using namespace std;

FILE*f=fopen("aliens.in","r");
FILE*g=fopen("aliens.out","w");

int n;
int p2[maxn],p3[maxn],p5[maxn],sol[maxcif],aux[maxcif];
short int D[maxlog1*maxn>>1][maxlog2*maxn>>1];

inline void desc ( int n , const int &val , int &p2 , int &p3 , int &p5 ){

    while ( n % 2 == 0 ){
        p2 += val; n /= 2;
    }
    while ( n % 3 == 0 ){
        p3 += val; n /= 3;
    }
    while ( n % 5 == 0 ){
        p5 += val; n /= 5;
    }
}

inline void copiaza ( int *A , int *B ){

    for ( int i = 0 ; i <= B[0] ; ++i ){
        A[i] = B[i];
    }
}

inline void aduna ( int *A , int *B ){
    int T = 0;

    A[0] = max(A[0],B[0]);
    for ( int i = 1 ; i <= A[0] ; ++i ){
        A[i] += B[i]+T;
        if ( A[i] >= 10 ){
            A[i] -= 10; T = 1;
        }
        else{
            T = 0;
        }
    }

    if ( T ){
        A[++A[0]] = 1;
    }
}

int main () {

    fscanf(f,"%d",&n);
    int x,y;
    for ( int i = 1 ; i <= n ; ++i ){
        fscanf(f,"%d %d",&x,&y);
        desc(x,1,p2[i],p3[i],p5[i]); desc(y,-1,p2[i],p3[i],p5[i]);
    }

    int middle3 = (maxlog1*maxn/4),middle5 = (maxlog2*maxn/4);
    for ( int i = 0 ; i < (middle3<<1) ; ++i ){
        for ( int j = 0 ; j < (middle5<<1) ; ++j ){
            D[i][j] = -inf;
        }
    }
    D[middle3][middle5] = 0;

    for ( int i = 1 ; i <= n ; ++i ){

        int start1,pas1,start2,pas2;
        if ( p3[i] >= 0 ){
            start1 = (middle3<<1)-1; pas1 = -1;
        }
        else{
            start1 = 0; pas1 = 1;
        }
        if ( p5[i] >= 0 ){
            start2 = (middle5<<1)-1; pas2 = -1;
        }
        else{
            start2 = 0; pas2 = 1;
        }

        for ( int a = start1 ; a < (middle3<<1) && a >= 0 ; a += pas1 ){
            if ( !(a+p3[i] < (middle3<<1) && a+p3[i] >= 0) )    continue ;
            for ( int b = start2 ; b < (middle5<<1) && b >= 0 ; b += pas2 ){
                if ( !(b+p5[i] < (middle5<<1) && b+p5[i] >= 0) )    continue ;
                if ( D[a][b] != -inf ){
                    D[a+p3[i]][b+p5[i]] = max(D[a+p3[i]][b+p5[i]],(short int)(D[a][b]+p2[i]));
                }
            }
        }
    }

    int a = 0,b = 0,c = 0; double best = 0;
    double doi = log(2),trei = log(3),cinci = log(5);
    for ( int i = middle3 ; i < (middle3<<1) ; ++i ){
        for ( int j = middle5 ; j < (middle5<<1) ; ++j ){
            if ( D[i][j] < 0 )   continue ;
            double now = (i-middle3)*trei + (j-middle5)*cinci + D[i][j]*doi;
            if ( now > best ){
                a = i-middle3,b = j-middle5,c = D[i][j],best = now;
            }
        }
    }

    sol[0] = sol[1] = 1;
    for ( int i = 1 ; i <= c ; ++i ){
        copiaza(aux,sol);
        aduna(sol,aux);
    }
    for ( int i = 1 ; i <= a ; ++i ){
        copiaza(aux,sol);
        aduna(sol,aux); aduna(sol,aux);
    }
    for ( int i = 1 ; i <= b ; ++i ){
        copiaza(aux,sol);
        aduna(sol,aux); aduna(sol,aux); aduna(sol,aux); aduna(sol,aux);
    }

    for ( int i = sol[0] ; i >= 1 ; --i ){
        fprintf(g,"%d",sol[i]);
    }
    fprintf(g,"\n");

    fclose(f);
    fclose(g);

    return 0;
}