Cod sursa(job #622052)

Utilizator andra23Laura Draghici andra23 Data 17 octombrie 2011 11:58:03
Problema Pavare2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.78 kb
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<algorithm>

using namespace std;

const int MAXN = 105;
const int MAXDIGITS = 35;
const int b = 1000000000;
int c[MAXN][5][MAXN][MAXDIGITS], solution[MAXN];
int k[MAXDIGITS], result[MAXDIGITS];

void readBigNumber(int v[], ifstream &f) {
	char s[MAXDIGITS*10];
	f >> s;
	int len = strlen(s);
	for (int i = len-1; i >= 0; i -= 9) {
		v[0]++;
		for (int j = max(0, i-8); j <= i; j++) {
			v[v[0]] = v[v[0]]*10 + s[j] - '0'; 		
		}
	}
}

void displayBigNumber(int v[], ofstream &g) {
	g << v[v[0]];
	for (int i = v[0]-1; i >= 1; i--) 
		g << setw(9) << setfill('0') << v[i];
}

void addBigNumber(int a[], int c[]) {
	int t = 0, i;
	for (i = 1; a[i] > 0 || c[i] > 0 || t; i++) {
		a[i] = a[i] + c[i] + t;
		t = a[i]/b;
		a[i] = a[i]%b;
	}
	a[0] = i-1;
}

void decreaseBigNumber(int a[], int c[]) {
	int t = 0, i;
	for (i = 1; a[i] > 0 || c[i] > 0 || t; i++) {
		a[i] = a[i] - c[i] - t;
		t = 0;
		if (a[i] < 0) {
			a[i] = a[i] + b;
			t = 1;
		}
	}
	a[0] = 0;
	for (i = 1; a[i] > 0; i++, a[0]++);
}

// returns 1 if first is bigger than second
int compareBigNumbers(int a[], int c[]) {
	if (a[0] > c[0]) {
		return true;
	} 
	if (a[0] < c[0]) {
		return false;
	}
	int i;
	for (i = a[0]; i > 1 && a[i] == c[i]; i--);
	return a[i] > c[i];
}

void findKthSolution(int n, int position, int stoneType, int k[], int ab[], int solution[]) {
	int start, end, delta;
	
	if (stoneType == 0) {
		start = ab[0];
		end = 0;
		delta = -1;
	} else {
		start = 1;
		end = ab[1] + 1;
		delta = 1;
	}

	int i, stones = start;
	for (i = start; i != end && k > 0; i = i + delta, stones = stones + delta) {
		if (compareBigNumbers(k, c[position][stoneType][i])) {
			decreaseBigNumber(k, c[position][stoneType][i]);
		} else {
			break;
		}
	}

	int solutionPos = n - position + 1;
	for (i = solutionPos; i < solutionPos + stones; i++) {
		solution[i] = stoneType;
	}

	if (position - stones > 0)
		findKthSolution(n, position-stones, 1-stoneType, k, ab, solution);
}

int main() {
	ifstream f("pavare2.in");
	ofstream g("pavare2.out");

	int n, a, b;
	f >> n >> a >> b;
	int ab[] = {a, b};

	readBigNumber(k, f);

	c[1][1][1][0] = 1;
	c[1][1][1][1] = 1;
	c[1][0][1][0] = 1;
	c[1][0][1][1] = 1;

	for (int i = 1; i <= n-1; i++) {
		for (int j = 0; j <= 1; j++) {
			for (int k = 1; k <= ab[j]; k++) {
				if (c[i][j][k][0] != 0) {
					if (k + 1 <= ab[j])
						addBigNumber(c[i+1][j][k+1], c[i][j][k]);
					addBigNumber(c[i+1][1-j][1], c[i][j][k]);
				}
			}
		}
	}

	result[0] = 1;
	result[1] = 0;
	for (int i = 0; i <= 1; i++) {
		for (int j = 1; j <= ab[i]; j++) {
			addBigNumber(result, c[n][i][j]);
		}
	}
	displayBigNumber(result, g);
	g << '\n';

	findKthSolution(n, n, 0, k, ab, solution);

	for (int i = 1; i <= n; i++) {
		g << solution[i];
	}
	g << '\n';

	return 0;
}