Cod sursa(job #163689)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 22 martie 2008 14:58:01
Problema Vanatoare Scor 5
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>
#include <map>
using namespace std;

#define ll long long
#define ii pair<int,int>
#define mp make_pair
struct comp {
	bool  operator()(ii x, ii y) { return x.first>y.first; }
};

ll A[17][2];
int n,i,j;
map<ii,int> C;
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 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);
		int nrb=1, ins=1;
		x = A[j][0]; cm = A[j][1];
        ++j;
		for (; j<n; ++j)
			if ( i & (j<<1) ) {
				nrb++;
				if ( cm % A[j][1] == 0 && x%A[j][1] != A[j][0] )  {
					ins = -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 ) {
					ins = -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;
					ins = -1; break;
				}
				if ( z<0 ) {
					z += ((-z)/cm+1)*cm;
				}
				x = z;
			}
		if ( ins!=-1 )
			C[mp(nrb, i)]=(int)x;
	}

	map<ii,int, comp>::reverse_iterator it;
	int nrd = 0;
	for (it=C.rbegin(); nrd<nr-1 && it!=C.rend(); ++it) {
		i = it->first.second;
		j = it->second;
		if ( (nrd&i)==0 )
			V[nrv++] = j, nrd |= i;
	}
	freopen("vanatoare.out", "w", stdout);
	printf("%d\n", nrv);
	for (i=0; i<nrv; ++i)
		printf("%d ", V[i]);

	return 0;
}