Cod sursa(job #7182)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 21 ianuarie 2007 12:59:06
Problema Aprindere Scor 5
Compilator cpp Status done
Runda preONI 2007, Runda 1, Clasa a 9-a si gimnaziu Marime 2.01 kb
#include <cstdio>
#include <vector>
#include <map>

using namespace std;

#define MAXN 1024
#define VSIZE 32

inline void set1(vector<int> &x, int poz) { x[poz >> 5] |= (1 << (poz & 31)); }
inline int get(vector<int> &x, int poz) { return x[poz >> 5] & (1 << (poz & 31)); }
inline void xorit(vector<int> &a, vector<int> &b)
{
	int i;
	for (i = 0; i < VSIZE; i++)
		a[i] ^= b[i];
}

int N, M;

char hastrans[MAXN];
vector<int> trans[MAXN];
int transT[MAXN];

vector<int> x(VSIZE);

map< pair< vector<int>, int >, int > C;
vector< pair< vector<int>, int> > lst[1005];

#define lst(i) lst[(i) % 1005]

void print( pair< vector<int>, int > x )
{
	int i;
	for (i = 0; i < N; i++)
		printf("%d", get(x.first, i) > 0);
	printf(" %d\n", x.second);
}

int main()
{
	freopen("aprindere.in", "rt", stdin);
	freopen("aprindere.out", "wt", stdout);
	scanf("%d %d", &N, &M);
	int i;
	for (i = 0; i < N; i++)
	{
		int k;
		scanf("%d", &k);
		if (k)
			set1(x, i);
	}
	for (i = 0; i < M; i++)
	{
		int poz, T, nr;
		scanf("%d %d %d", &poz, &T, &nr);
		hastrans[poz] = 1;
		transT[poz] = T;
		trans[poz].resize(VSIZE, 0);
		for (; nr; nr--)
		{
			int k;
			scanf("%d", &k);
			set1( trans[poz], k );
		}
	}

	for (i = 0; get(x, i); i++);
	C[ make_pair(x, i) ] = 0;
	lst[0].push_back( make_pair(x, i) );

	int NR = 1, CST = 0;
	pair< vector<int>, int > tmp;
	for (; NR; CST++)
	{
		vector< pair< vector<int>, int > > :: iterator it;
		for (it = lst(CST).begin(); it != lst(CST).end(); it++, NR--)
		{
			int poz, cC, nC;
			cC = C[*it];
			if (cC != CST) continue;

			x = (*it).first;
			poz = (*it).second;
			if (poz == N)
			{
				printf("%d\n", cC);
				return 0;
			}
	
			xorit(x, trans[poz]);

			nC = cC + transT[poz];
			for (; get(x, poz); poz++);
			if (poz != N && !hastrans[poz])
				continue;

			tmp = make_pair( x, poz );
			if (C.find( tmp ) != C.end())
				if (nC < C[tmp])
				{
					C[tmp] = nC;
					lst(nC).push_back( tmp );
					NR++;
				}
				else;
			else
			{
				C[tmp] = nC;
				lst(nC).push_back( tmp );
				NR++;
			}
		}
	}
	return 0;
}