Cod sursa(job #1857088)

Utilizator contnouAndrei Pavel contnou Data 25 ianuarie 2017 20:00:23
Problema Copii Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 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 &childrenCount) {
	//
	f >> childrenCount;

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

	return;
}

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

	memset(visited, 0, MAXK * sizeof(int));

	for (int i = 0; i < groupsCount; i++) {
		//
		visitedGroups = 0;
		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]] != i + 1) && (children[child - 1][k - 1] == '1')) {
					visitedGroups++;
					visited[assignedGroup[k]] = i + 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 (prevmax[pos] > 0 && isSolution(children, childGroup, len, prevmax[pos] + 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;
}