Cod sursa(job #110663)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 27 noiembrie 2007 11:06:22
Problema Aliens Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
// Mai bagi peste 100 milioane in 0.2 sec
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int BAZA = 10000;
const int LMAX = 256;
const int NP = 3;
const int PMAX = 30;
const int P[] = {2, 3, 5};
const int NMAX = 51;
const int MMAX = NMAX << 1;
const int MLOG3 = 19;
const int MLOG5 = 13;
const double ln2 = log(2);
const double ln3 = log(3);
const double ln5 = log(5);

int N, A[NMAX], B[NMAX], best2, best3, best5;
short DP[MMAX * MLOG3][MMAX * MLOG5];
int R[LMAX];

void read(void) {
	FILE *fin = fopen("aliens.in", "rt");
	int i;

	fscanf(fin, " %d", &N);

	for (i = 1; i <= N; ++i)
		fscanf(fin, " %d %d", A + i, B + i);
	fclose(fin);
}

int simple(int a, int p) {
	int rez = 0;

	while (a % p == 0)
		++rez, a /= p;
	
	return rez;
}

void solve(void) {
	int b3, e3, b5, e5, s3, f3 = 0, s5, f5 = 0, pas3, pas5;
	int i, i3, i5, v2, v3, v5;

	memset(DP, 0xd0, sizeof(DP));

	DP[b3 = e3 = NMAX * MLOG3][b5 = e5 = NMAX * MLOG5] = 0;

	for (i = 1; i <= N; ++i) {
		v2 = simple(A[i], 2) - simple(B[i], 2);
		v3 = simple(A[i], 3) - simple(B[i], 3);
		v5 = simple(A[i], 5) - simple(B[i], 5);

//		printf("i=%d => %d %d %d\n", i, v2, v3, v5);

		if (v3 <= 0)
			s3 = b3, f3 = e3 + 1, pas3 = 1;
		else
			s3 = e3, f3 = b3 - 1, pas3 = -1;
		if (v5 <= 0)
			s5 = b5, f5 = e5 + 1, pas5 = 1;
		else
			s5 = e5, f5 = b5 - 1, pas5 = -1;

		for (i3 = s3; i3 != f3; i3 += pas3)
			for (i5 = s5; i5 != f5; i5 += pas5) {
				short &p = DP[i3 + v3][i5 + v5];
				p = max(p, (short)(DP[i3][i5] + v2));
//				printf("got %d %d => %hd\n", i3, i5, p);
			}

		if (v3 < 0) b3 += v3; else e3 += v3;
		if (v5 < 0) b5 += v5; else e5 += v5;
	}

	for (i3 = NMAX * MLOG3, v3 = 0; i3 <= e3; ++i3, ++v3)
		for (i5 = NMAX * MLOG5, v5 = 0; i5 <= e5; ++i5, ++v5) {
			short p = DP[i3][i5];

			if (p < 0) continue;

			if ( (best2 - p) * ln2 + (best3 - v3) * ln3 + (best5 - v5) * ln5 < 0.)
				best2 = p, best3 = v3, best5 = v5;
		}
	
//	printf("BEST: %d %d %d\n", best2, best3, best5);
}

void mult(int R[], int k) {
	int t, i;

	for (i = 1, t = 0; i <= R[0] || t; ++i, t /= BAZA)
		R[i] = (t += R[i] * k) % BAZA;
}

void write(void) {
	FILE *fout = fopen("aliens.out", "wt");
	int i;

	R[ R[0] = 1 ] = 1;

	for (i = 0; i < best2; ++i)
		mult(R, 2);
	for (i = 0; i < best3; ++i)
		mult(R, 3);
	for (i = 0; i < best5; ++i)
		mult(R, 5);
	
	fprintf(fout, "%d", R[R[0]]);
	for (i = R[0] - 1; i > 0; --i)
		fprintf(fout, "%.4d", R[i]);
	fprintf(fout, "\n");

	fclose(fout);
}

int main(void) {
	
	read();

	solve();

	write();

	return 0;
}