Cod sursa(job #109894)

Utilizator Omega91Nicodei Eduard Omega91 Data 25 noiembrie 2007 12:54:13
Problema Economie Scor 20
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasa a 10-a Marime 1.62 kb
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
	fstream f;
	int n, i, max = 0, aux, k = 0, v[1001], vback[1001], a[1001], j, poz, s;
	bool x[50001] = {}, cont, bun;
	f.open("economie.in", ios::in);
	f >> n;
	//citim
	for (i = 0; i < n; ++i) {
		f >> aux;
		if ( aux > max ) max = aux;
		x[aux] = true;
	}
	f.close(); //inchis fisier
	//sortam
	++max;
	for (i = 1; i < max; ++i)
		if ( x[i] ) v[++k] = i;
	f.open("economie.out", ios::out);
	if (v[1] == 1) {
		f << "1" << endl << "1" << endl;
		f.close();
		return 0;
	}
	//incepem
	k = 1; //cate elemente avem in a
	a[1] = v[1];
	for (i = 2; i <= n; ++i) {
		cont = false;
		//mai intai verifivam cu impartirea
		for (j = k; j > 0; --j)
			if ( !(v[i] % a[j]) ) {
				cont = true;
				break;
			}
		if (cont) continue;
		if (k == 1) {
			a[++k] = v[i];
			continue;
		}
		//apoi cu 2 numere
		if (k == 2) {
			cont = true;
			aux = v[i];
			while (aux > 0) {
				aux -= a[2];
				if ( !(aux % a[1]) ) {
					cont = false;
					break;
				}
			}
			if (cont) a[++k] = v[i];
			continue;
		}
		//acuma backtrack si atata
		cont = true;
		poz = 1;
		vback[poz] = -1;
		while (poz > 0) {
			bun = false;
			++vback[poz];
			//verificare
			s = 0;
			for (j = 1; j <= poz; ++j)
				s += vback[j] * a[j];
			if (s <= v[i]) bun = true;
			if (!bun) --poz;
			else if (poz == k) {
				s = v[i] - s;
				for (j = 1; j <= k; ++j)
					if ( !(s % a[j]) ) {
						cont = false;
						poz = -1;
						break;
					}
			}
			else {
				++poz;
				vback[poz] = -1;
			}
		}
		if ( cont ) a[++k] = v[i];
	}
	f << k << endl;
	for (i = 1; i <= k; ++i) {
		f << a[i] << endl;
	}
	f.close();
	return 0;
}