Cod sursa(job #2064738)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 12 noiembrie 2017 19:00:45
Problema Aliens Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.95 kb
#include <cstdio>
#include <cmath>

FILE *fin = fopen("aliens.in", "r"), *fout = fopen("aliens.out", "w");

#define INF 10000

#define MAX5 12
#define MAX3 18
#define MAXN 50

const int A = MAXN * MAX5, B = MAXN * MAX3;
const int K = 450;

int p2, p3, p5, p, q, u, v;
int ans[K];
short int dp[2 * A + 1][2 * B + 1];

inline short int mymax(short int a, short int b) {
    if (a > b) return a;
    else return b;
}

inline void inmult(int a[], int x) {
    int tr = 0, i = 1;
    while (i <= a[0] || tr) {
        tr += a[i] * x;
        a[i] = tr % 10;
        tr /= 10;
        i++;
    }
    i--;
    if (i > a[0])
        a[0] = i;
}

inline void vezi(int a, int add) {
    while (a % 2 == 0) p2 += add, a /= 2;
    while (a % 3 == 0) p3 += add, a /= 3;
    while (a % 5 == 0) p5 += add, a /= 5;
}

inline void solve() {
    int a, b;
    fscanf(fin, "%d%d", &a, &b);

    p2 = p3 = p5 = 0;
    vezi(a, 1);
    vezi(b, -1);

    if (p5 > 0) {
        q += p5;
        if (p3 > 0) {
            v += p3;
            for (int i = q; i - p5 >= p; i--)
                for (int j = v; j - p3 >= u; j--)
                    dp[i][j] = mymax(dp[i][j], dp[i - p5][j - p3] + p2);
        } else {
            u += p3;
            for (int i = q; i - p5 >= p; i--)
                for (int j = u; j - p3 <= v; j++)
                    dp[i][j] = mymax(dp[i][j], dp[i - p5][j - p3] + p2);
        }
    } else {
        p += p5;
        if (p3 > 0) {
            v += p3;
            for (int i = p; i - p5 <= q; i++)
                for (int j = v; j - p3 >= u; j--)
                    dp[i][j] = mymax(dp[i][j], dp[i - p5][j - p3] + p2);
        } else {
            u += p3;
            for (int i = p; i - p5 <= q; i++)
                for (int j = u; j - p3 <= v; j++)
                    dp[i][j] = mymax(dp[i][j], dp[i - p5][j - p3] + p2);
        }
    }
}

int main() {
    for (int i = 0; i <= 2 * A; i++)
        for (int j = 0; j <= 2 * B; j++)
            dp[i][j] = -INF;
    dp[A][B] = 0;
    p = q = A;
    v = u = B;

    int n;
    for (fscanf(fin, "%d", &n); n; n--)
        solve();

    double best = -1;
    int a = 0, b = 0, c = 0;
    for (int i = A; i <= 2 * A; i++) {
        for (int j = B; j <= 2 * B; j++) {
            if (dp[i][j] >= 0) {
                double e = log(2) * dp[i][j] + log(3) * (j - B) + log(5) * (i - A);
                if (e > best) {
                    best = e;
                    a = dp[i][j];
                    b = j - B;
                    c = i - A;
                }
            }
        }
    }

    ans[0] = ans[1] = 1;
    for (int i = 0; i < a; i++)
        inmult(ans, 2);
    for (int i = 0; i < b; i++)
        inmult(ans, 3);
    for (int i = 0; i < c; i++)
        inmult(ans, 5);

    for (int i = ans[0]; i > 0; i--)
        fputc(ans[i] + '0', fout);
    fputc('\n', fout);

    fclose(fin);
    fclose(fout);
    return 0;
}