Cod sursa(job #733992)

Utilizator darrenRares Buhai darren Data 13 aprilie 2012 12:17:23
Problema Pavare2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <cstring>
#include <fstream>
#include <algorithm>

using namespace std;

const int NUM = 25;
const int BASE = 8;
const int PBASE = 100000000;

class big
{
	public:
		int V[NUM];
		
		big()
		{
			memset(V, 0, sizeof(V));
			V[0] = 1;
		}
		
		void operator += (const big& A)
		{
			V[0] = max(V[0], A.V[0]);
			for (int i = 1; i <= V[0]; ++i)
			{
				V[i] += A.V[i];
				if (V[i] >= PBASE)
				{
					V[i + 1] += V[i] / PBASE;
					V[i] %= PBASE;
					V[0] += (i == V[0]);
				}
			}
		}
		void operator -= (const big& A)
		{
			for (int i = 1; i <= V[0]; ++i)
			{
				V[i] -= A.V[i];
				if (V[i] < 0)
				{
					V[i] += PBASE;
					--V[i + 1];
				}
			}
			while (V[0] > 1 && V[V[0]] == 0)
				--V[0];
		}
		bool operator < (const big& A)
		{
			if (V[0] != A.V[0])
				return V[0] < A.V[0];
			for (int i = V[0]; i >= 1; --i)
				if (V[i] != A.V[i])
					return V[i] < A.V[i];
			return false;
		}
};
void convert(char* C, big& num)
{
	int i;
	for (i = 0; C[i] != '\0'; ++i)
		num.V[i + 1] = C[i] - '0';
	num.V[0] = i;
	reverse(num.V + 1, num.V + i + 1);
}

int N, A, B;
char pK[NUM];
big oldK, K, P[102][102][2];

int main()
{
	ifstream fin("pavare2.in");
	ofstream fout("pavare2.out");
	
	fin >> N >> A >> B >> pK;
	convert(pK, oldK);
	
	P[1][1][0].V[1] = 1, P[1][1][1].V[1] = 1;
	for (int i = 2; i <= N; ++i)
	{
		for (int j = 2; j <= min(A, i); ++j)
			P[i][j][0] += P[i - 1][j - 1][0];
		for (int j = 2; j <= min(B, i); ++j)
			P[i][j][1] += P[i - 1][j - 1][1];
		for (int j = 1; j <= B; ++j)
			P[i][1][0] += P[i - 1][j][1];
		for (int j = 1; j <= A; ++j)
			P[i][1][1] += P[i - 1][j][0];
	}
	
	big result;
	for (int j = 1; j <= max(A, B); ++j)
	{
		result += P[N][j][0];
		result += P[N][j][1];
	}
	
	fout << result.V[result.V[0]];
	for (int i = result.V[0] - 1; i >= 1; --i)
	{
		int cif = 0, aux = result.V[i];
		while (aux)
		{
			++cif;
			aux /= 10;
		}
		
		for (int j = 1; j <= BASE - cif; ++j)
			fout << '0';
		fout << result.V[i];
	}
	fout << '\n';
	
	for (int i = 1; i <= oldK.V[0]; i += 8)
	{
		int number = 0;
		for (int j = min(oldK.V[0], i + 7); j >= i; --j)
			number = number * 10 + oldK.V[j];
		K.V[i / 8 + 1] = number;
		++K.V[0];
	}
	--K.V[0];
	
	int done = N;
	bool skip0 = false;
	
	while (done)
	{
		bool found = false;
		if (!skip0)
		{
			for (int i = min(A, done); i >= 1; --i)
				if (P[done][i][0] < K)
					K -= P[done][i][0];
				else
				{
					found = true;
					skip0 = true;
					for (int j = 1; j <= i; ++j)
						fout << '0';
					done -= i;
					break;
				}
		}
		if (!found)
		{
			for (int i = 1; i <= min(B, done); ++i)
				if (P[done][i][1] < K)
					K -= P[done][i][1];
				else
				{
					skip0 = false;
					for (int j = 1; j <= i; ++j)
						fout << '1';
					done -= i;
					break;
				}
		}
	}
	
	fin.close();
	fout.close();
}