Cod sursa(job #1743379)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 18 august 2016 02:43:03
Problema Aliens Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.95 kb
#include <fstream>
#include <algorithm>
#include <cmath>
using namespace std;

ifstream cin("aliens.in");
ofstream cout("aliens.out");

const int MAXN = 60;
const int MAXLOG3 = 20;
const int MAXLOG5 = 15;
const int INF = 1000000;
const int MAXD = 500;

int p2[1 + MAXN], p3[1 + MAXN], p5[1 + MAXN];
int dp[MAXLOG3 * MAXN / 2][MAXLOG5 * MAXN / 2];
int v[MAXD];

void Decompose(int value, int add, int index) {
    while (value % 2 == 0) {
        value /= 2;
        p2[index] += add;
    }
    while (value % 3 == 0) {
        value /= 3;
        p3[index] += add;
    }
    while (value % 5 == 0) {
        value /= 5;
        p5[index] += add;
    }
}

void Multiply(int a[], int k) {
    int c = 0;
    for (int i = 1; i <= a[0]; i++) {
        a[i] = a[i] * k + c;
        c = a[i] / 10;
        a[i] %= 10;
    }
    while (c > 0) {
        a[0]++;
        a[a[0]] = c % 10;
        c /= 10;
    }
}

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int x, y;
        cin >> x >> y;
        Decompose(x, 1, i);
        Decompose(y, -1, i);
    }
    int zero3 = (MAXLOG3 * MAXN / 4), zero5 = (MAXLOG5 * MAXN / 4);
    for (int i = 0; i < zero3 * 2; i++)
        for (int j = 0; j < zero5 * 2; j++)
            dp[i][j] = -INF;
    dp[zero3][zero5] = 0;
    for (int i = 1; i <= n; i++) {
        int start3, step3, start5, step5;
        if (p3[i] >= 0) {
            start3 = (zero3 * 2) - 1;
            step3 = -1;
        }
        else {
            start3 = 0;
            step3 = 1;
        }
        if (p5[i] >= 0) {
            start5 = (zero5 * 2) - 1;
            step5 = -1;
        }
        else {
            start5 = 0;
            step5 = 1;
        }
        for (int a = start3; a < zero3 * 2 && a >= 0; a += step3)
            if (a + p3[i] < zero3 * 2 && a + p3[i] >= 0)
                for (int b = start5; b < zero5 * 2 && b >= 0; b += step5)
                    if (b + p5[i] < zero5 * 2 && b + p5[i] >= 0)
                        if (dp[a][b] != INF)
                            dp[a + p3[i]][b + p5[i]] = max(dp[a + p3[i]][b + p5[i]], dp[a][b] + p2[i]);
    }
    double best = 0, two = log(2), three = log(3), five = log(5);
    int a, b, c;
    for (int i = zero3; i < zero3 * 2; i++)
        for (int j = zero5; j < zero5 * 2; j++)
            if (dp[i][j] >= 0) {
                double value = (i - zero3) * three + (j - zero5) * five + dp[i][j] * two;
                if (value > best) {
                    best = value;
                    a = i - zero3;
                    b = j - zero5;
                    c = dp[i][j];
                }
            }
    v[0] = v[1] = 1;
    for (int i = 1; i <= a; i++)
        Multiply(v, 3);
    for (int i = 1; i <= b; i++)
        Multiply(v, 5);
    for (int i = 1; i <= c; i++)
        Multiply(v, 2);
    for (int i = v[0]; i >= 1; i--)
        cout << v[i];
    cout << "\n";
    return 0;
}