Cod sursa(job #733960)

Utilizator darrenRares Buhai darren Data 13 aprilie 2012 11:29:09
Problema Pavare2 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <cstring>
#include <fstream>
#include <algorithm>

using namespace std;

const int NUM = 300;

class big
{
	public:
		int V[NUM];
		
		big()
		{
			memset(V, 0, sizeof(V));
			V[0] = 1;
		}
		
		big operator += (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] >= 10)
				{
					V[i + 1] += V[i] / 10;
					V[i] %= 10;
					V[0] += (i == V[0]);
				}
			}
			return *this;
		}
		big operator -= (big A)
		{
			for (int i = 1; i <= V[0]; ++i)
			{
				V[i] -= A.V[i];
				if (V[i] < 0)
				{
					V[i] += 10;
					--V[i + 1];
				}
			}
			while (V[0] > 1 && V[V[0]] == 0)
				--V[0];
			return *this;
		}
		bool operator < (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);
}
big convert(int C)
{
	big num;
	while (C)
	{
		num.V[++num.V[0]] = C % 10;
		C /= 10;
	}
	return num;
}

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

int main()
{
	ifstream fin("pavare2.in");
	ofstream fout("pavare2.out");
	
	fin >> N >> A >> B >> pK;
	convert(pK, K);
	
	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];
	}
	
	for (int i = result.V[0]; i >= 1; --i)
		fout << result.V[i];
	fout << '\n';
	
	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();
}