Cod sursa(job #1433654)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 9 mai 2015 17:32:09
Problema Aliens Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.6 kb
#include <fstream>
#include <algorithm>
#include <cmath>
#include <cstring>

using namespace std;

#define inFile "aliens.in"
#define outFile "aliens.out"
#define MAX_N 50
#define AXIS 40
#define MAX_DIG 500
#define UNDEFINED 0x7fffffff

ifstream in(inFile);
ofstream out(outFile);

class Huge {
private:
    int x[MAX_DIG];
public:
    void print();
    Huge();
    Huge(int k);
    Huge operator *(int k);
    Huge operator *(const Huge &other);
};

struct Element {
    int e2;
    int e3;
    int e5;
};

Element E[MAX_N + 1];
int D[MAX_N + 1][AXIS*2 + 1][AXIS*2 + 1];

Huge buildNr(int e2, int e3, int e5);
Huge raisePower(int base, int exp);
void decompose(int k, int sgn, int i);
bool compare(Element A, Element B);

int main() {
    int N, i, j, k, num, denom;
    
    in >> N;
    for(i = 1; i <= N; i++) {
        in >> num >> denom;
        decompose(num, 1, i);
        decompose(denom, -1, i);
    }
    
    for(i = 0; i <= N; i++) {
        for(j = -AXIS; j <= AXIS; j++) {
            for(k = -AXIS; k <= AXIS; k++) {
                D[i][j+AXIS][k+AXIS] = UNDEFINED;
            }
        }
    }
    
    D[1][E[1].e3+AXIS][E[1].e5+AXIS] = E[1].e2;
    D[1][0+AXIS][0+AXIS] = 0;
    for(i = 2; i <= N; i++) {
        for(j = -AXIS; j <= AXIS; j++) {
            for(k = -AXIS; k <= AXIS; k++) {
                if(D[i-1][j+AXIS][k+AXIS] != UNDEFINED) {
                    D[i][j+AXIS][k+AXIS] = D[i-1][j+AXIS][k+AXIS]; 
                    if(j+AXIS >= E[i].e3 && k+AXIS >= E[i].e5 && D[i-1][j+AXIS-E[i].e3][k+AXIS-E[i].e5] != UNDEFINED)
                        D[i][j+AXIS][k+AXIS] = max(D[i-1][j+AXIS-E[i].e3][k+AXIS-E[i].e5] + E[i].e2, D[i][j+AXIS][k+AXIS]);
                }
                else {
                    if(j+AXIS >= E[i].e3 && k+AXIS >= E[i].e5 && D[i-1][j+AXIS-E[i].e3][k+AXIS-E[i].e5] != UNDEFINED)
                        D[i][j+AXIS][k+AXIS] = D[i-1][j+AXIS-E[i].e3][k+AXIS-E[i].e5] + E[i].e2;
                }
            }
        }
    }
        
    /*for(i = 1; i <= N; i++) {
        for(j = -AXIS; j <= AXIS; j++) {
            for(k = -AXIS; k <= AXIS; k++) {
                out << "I " << i << " J " << j << " K " << k << " ---> " << D[i][j+AXIS][k+AXIS] << '\n';
            }
        }
    }*/
        
    Element MAX = {-AXIS, -AXIS, -AXIS}, curr;
    Huge ANS;
    for(i = 0; i <= AXIS; i++) {
        for(j = 0; j <= AXIS; j++) {
            if(D[N][i+AXIS][j+AXIS] >= 0 && D[N][i+AXIS][j+AXIS] != UNDEFINED) {
                curr.e2 = D[N][i+AXIS][j+AXIS];
                curr.e3 = i;
                curr.e5 = j;
                if(compare(curr, MAX)) 
                    MAX = curr;
            }
        }
    }
    
    ANS = buildNr(MAX.e2, MAX.e3, MAX.e5);
    ANS.print();
    
    return 0;
}

void decompose(int k, int sgn, int i) {
    while(k % 2 == 0)
        k /= 2, E[i].e2 += sgn;
    while(k % 3 == 0)
        k /= 3, E[i].e3 += sgn;
    while(k % 5 == 0)
        k /= 5, E[i].e5 += sgn;
}

bool compare(Element A, Element B) {
    return (double)A.e2*log(2) + (double)A.e3*log(3) + (double)A.e5*log(5) >(double) B.e2*log(2) + (double)B.e3*log(3) + (double)B.e5*log(5);
}

Huge :: Huge() {
    memset(x, 0, sizeof(x));
    x[0] = 1;
}

Huge :: Huge(int k) {
    memset(x, 0, sizeof(x));
    do {
        x[++x[0]] = k % 10;
        k /= 10;
    } while(k);
}

Huge Huge :: operator *(int k) {
    int i, t;
    Huge ans;
    
    ans.x[0] = x[0];
    for(i = 1, t = 0; i <= x[0]; i++) {
        ans.x[i] = x[i]*k + t;
        t = ans.x[i] / 10;
        ans.x[i] %= 10;
    }
    while(t) {
        ans.x[++ans.x[0]] = t % 10;
        t /= 10;
    }
    return ans;
}

void Huge :: print() {
    int i;
    for(i = x[0]; i; i--)
        out << x[i];
    out << '\n';
}

Huge Huge :: operator *(const Huge &other) {
    int i, j, t;
    Huge ans;
    
    ans.x[0] = x[0] + other.x[0] - 1;
    for(i = 1; i <= x[0]; i++) 
        for(j = 1; j <= other.x[0]; j++)
            ans.x[i+j-1] += x[i] * other.x[j];
    for(i = 1, t = 0; i <= ans.x[0]; i++) {
        ans.x[i] += t;
        t = ans.x[i] / 10;
        ans.x[i] %= 10;
    }
    while(t) {
        ans.x[++ans.x[0]] = t % 10;
        t /= 10;
    }
    return ans;
}

Huge raisePower(int base, int exp) {
    int i;
    Huge ans(1);
    for(i = 1; i <= exp; i++)
        ans = ans * base;
    return ans;
}

Huge buildNr(int e2, int e3, int e5) {
    Huge ans(1);
    ans = ans * raisePower(2, e2);
    ans = ans * raisePower(3, e3);
    ans = ans * raisePower(5, e5);
    return ans;
}