Cod sursa(job #1857066)

Utilizator contnouAndrei Pavel contnou Data 25 ianuarie 2017 19:32:33
Problema Copii Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <fstream>
#include <string.h>
#include <vector>
#define MAXK 13

using namespace std;

ifstream f("copii.in");
ofstream g("copii.out");


void readData(char **&children, int &n) {
	//
	f >> n;

	children = new char*[n + 1];
	for (int i = 0; i < n; i++) {
		children[i] = new char[n + 1];
		f >> children[i];
	}

	return;
}

bool isSolution(char **children, int *assignedGroup, int childrenCount, int groupsCount) {
	//
	vector<int> groups[MAXK];
	int countRelations = 0;
	
	if (groupsCount < 2) return false;
	
	for (int i = 1; i <= childrenCount; i++) {
		groups[assignedGroup[i]].push_back(i);
	}

	for (int i = 0; i < groupsCount; i++) {
		//
		int visited[MAXK], visitedGroups = 0;
		memset(visited, 0, MAXK * sizeof(int));
	
		for (int j = 0; j < groups[i].size(); j++) {
			//
			int child = groups[i][j];
			for (int k = 1; k <= childrenCount; k++) {
				if (assignedGroup[child] != assignedGroup[k] && !visited[assignedGroup[k]] && children[child - 1][k - 1] == '1') {
					visitedGroups++;
					visited[assignedGroup[k]] = 1;
				}
			}
		}

		if (visitedGroups != groupsCount - 1) {
			return false;
		}
	}

	return true;
}

inline int getMax(int a, int b) {
	//
	return a > b ? a : b;
}

void combinations(char **children, int *childGroup, int pos, int len, int *prevmax, int &countTeams) {
	//
	for (int i = 0; i <= prevmax[pos - 1] + 1; i++) {
		//
		childGroup[pos] = i;
		prevmax[pos] = getMax(prevmax[pos - 1], i);

		if (pos < len) {
			combinations(children, childGroup, pos + 1, len, prevmax, countTeams);
		}
		else if (isSolution(children, childGroup, pos, getMax(prevmax[pos - 1], i) + 1)) {
			countTeams++;
		}
	}
}

int teamUp(char **children, int len) {
	//
	int childGroup[MAXK], prevmax[MAXK], countTeams = 0;
	memset(childGroup, 0, MAXK * sizeof(int));
	memset(prevmax, 0, MAXK * sizeof(int));

	childGroup[0] = -1;
	prevmax[0] = -1;

	combinations(children, childGroup, 1, len, prevmax, countTeams);

	return countTeams;
}

int main() {
	//
	int childCount;
	char **children = 0;
	int teams;

	readData(children, childCount);
	teams = teamUp(children, childCount);
	g << teams;

	return 0;
}