Cod sursa(job #163438)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 22 martie 2008 11:24:35
Problema Vanatoare Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda Finala, Clasele 11-12 Marime 1.89 kb
/*
 * facem submultimile in 2^n
 * gasim X pt o submultime = pozitia unde va trebui sa se afle ca sa omoare toti mistretii (daca se poate)
 * greedy ? 
 */

#include <cstdio>
#include <algorithm>
using namespace std;

#define ll long long

ll A[17][2];
int n,i,j;
int C[1<<17], O[1<<17], nrb[1<<17];
ll x, cm, c, p, x0, y0, z, t;
int V[17], nrv;


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

	ll xp, yp;
	ll d = euclid(b, a%b, xp, yp);
	x = yp;
	y = xp - yp*(a/b);
	return d;
}

void binary_print(int x) {
	int i;
	for (i=0; i<n; ++i)
		if ( x&(1<<i) )
			printf("1");
		else
			printf("0");
}

int comp(int x, int y) {
	return nrb[x]>nrb[y];
}

int main() {
	freopen("vanatoare.in", "r", stdin);
	scanf("%d %lld", &n, &t);
	for (i=0; i<n; ++i)
		scanf("%lld %lld", A[i], A[i]+1);

	int nr = 1<<n;
	for (i=1; i<nr; ++i) {
		for (j=0; j<n && !(i&(1<<j)); ++j);
		nrb[i]++;
		x = A[j][0]; cm = A[j][1];
        ++j;
		for (; j<n; ++j)
			if ( i & (j<<1) ) {
				nrb[i]++;
				if ( cm % A[j][1] == 0 && x%A[j][1] != A[j][0] )  {
					C[i] = -1; break;
				}
				c = A[j][0]-x;
				p = euclid(cm, -A[j][1], x0, y0);
                if ( p<0 ) p*=-1;
	            if ( c<0 ) c*=-1;

				if ( c%p!=0 ) {
					C[i] = -1; break;
				}
				x0 *= (c/p); y0 *= (c/p);
				z = cm*x0 + x;
				cm = (cm*A[j][1])/p;
				if ( z>t ) {					// nu e bine
                	x = z;
					C[i] = -1; break;
				}
				if ( z<0 ) {
					z += ((-z)/cm+1)*cm;
				}
				x = z;
			}
		if ( C[i]!=-1 )
			C[i] = (int)x;
		O[i]=i;
//		binary_print(i);
//		printf(" %ld\n", C[i]);
	}

	for (i=1; i<nr; ++i) {
		binary_print(O[i]);
		printf(" %d\n", C[O[i]]);
	}

	sort(O+1, O+nr, comp);
	int nrd = 0;
	for (i=0; nrd<nr-1 && i<nr; ++i) 
		if ( C[O[i]]>0 && (nrd&O[i])==0 ) 
			V[nrv++] = C[O[i]], nrd |= O[i];

	freopen("vanatoare.out", "w", stdout);
	printf("%d\n", nrv);
	for (i=0; i<nrv; ++i)
		printf("%d ", V[i]);
	return 0;
}