Cod sursa(job #163627)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 22 martie 2008 14:49:57
Problema Vanatoare Scor 5
Compilator cpp Status done
Runda preONI 2008, Runda Finala, Clasele 11-12 Marime 2.07 kb
#include <cstdio>
#include <cassert>
#include <algorithm>

using namespace std;

typedef long long llong;
typedef pair <int, int> PII;
#define x first
#define y second

const int NMAX = 1 << 16;

int N, T, DP[NMAX], F[NMAX], L[NMAX];
bool DNC[NMAX];
PII A[32];

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

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

	for (i = 0; i < N; ++i)
		fscanf(fin, " %d %d", &A[i].x, &A[i].y);

	fclose(fin);
}

int euclid(int a, int b, int *x, int *y) {
	if (b == 0) {
		*x = 1; *y = 0;
		return a;
	}

	int d, dx, dy;

	d = euclid(b, a % b, &dx, &dy);
	*x = dy;
	*y = dx - (a / b) * dy;
	
	return d;
}

void back(int k, int p, int i) {
	if (k == N) {
		DNC[p] = true;
		return;
	}

	back(k+1, p, i);
	if (i & (1 << k))
		back(k+1, p | (1 << k), i);
}

void solve(void) {
	int i, j, stop, cx, cy, d, auc, auv;
	llong C, V, v, x, y, p;

	memset(DP, 0x3f, sizeof(DP));
	DP[0] = 0;

	stop = 1 << N;
	for (i = 1; i < stop; ++i) {
		if (DNC[i]) continue;
		
		C = 1; V = 1;

		for (j = 0; j < N; ++j) {
			if ((i & (1 << j)) == 0) continue;

			v = C - A[i].x;

			if (V == 0 || V > T)
				if (v == 0) continue; else break;

			d = euclid((int) V, A[i].y, &cx, &cy);
			auc = C; auv = V;
			if (cx < 0) swap(cx, cy), swap(A[j].x, auc), swap(A[j].y, auv);
			x = cx; y = cy;
			printf("%d\n", i);
			printf("%lld %d %d\n", V, A[j].y, d);
			printf("%lld %lld %lld\n", x, y, v);
			printf("\n");

			if (v % d) break;
			x = x * v / d;
			y = y * v / d;
			v -= A[j].y * y;

			p = v / (V / d);
			v -= p * A[j].y;
			x = v / V;
			
			C += x * V;

			if (C > T) break;

			V = (V * A[j].y) / d;
		}

		if (j < N) continue;

		printf("for %d got %lld %lld\n", i, C, V);

		back(0, 0, i);

		for (j = 0; j < stop; ++j)
			if (DP[j | i] > DP[j] + 1)
				DP[j | i] = DP[j] + 1,
				L[j | i] = j,
				F[j | i] = C;
	}
}

void write(void) {
	FILE *fout = fopen("vanatoare.out", "wt");
	int i = (1 << N) - 1;

	fprintf(fout, "%d\n", DP[i]);
	for (; i; i = L[i])
		fprintf(fout, "%d ", F[i]);
	fprintf(fout, "\n");

	fclose(fout);
}

int main(void) {

	read();

	solve();

	write();

	return 0;
}