Cod sursa(job #2097744)

Utilizator arcoC. Nicolae arco Data 1 ianuarie 2018 15:58:53
Problema Jocul Flip Scor 20
Compilator c Status done
Runda Arhiva de probleme Marime 4.36 kb
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

typedef int mat;
typedef unsigned int uint;

mat **get_empty(mat rows, mat cols);
mat **read_matrix(mat rows, mat cols, FILE *from);
void free_matrix(mat **matrix, mat rows);
void tipar(mat **matrix, mat rows, mat cols, FILE *where);
int64_t sum(int **matrix, int n, int m);
void flip_row(int **matrix, int k, int m);
void flip_col(int **matrix, int n, int k);

void submultimi_backtrack_row(uint *stiva, uint nivel, uint n, int **matrix, int r, int c);
void submultimi_backtrack_col(uint *stiva, uint nivel, uint n, int **matrix, int r, int c);
void tipar_s(uint *stiva, uint nivel);
bool valid(uint *stiva, uint nivel, uint last);
int64_t max = 0;

int main(void)
{
	FILE *in = fopen("flip.in", "r");
	FILE *out = fopen("flip.out", "w");
	if(in != NULL && out != NULL)
	{
		int n, m;
		fscanf(in, "%d%*c%d%*c", &n, &m);

		int **matrix = read_matrix(n, m, in);
		uint stiva[20];
		submultimi_backtrack_row(stiva, 0, n, matrix, n, m);
		submultimi_backtrack_col(stiva, 0, n, matrix, n, m);
		fprintf(out, "%lld\n", max);

		free_matrix(matrix, n);
		fclose(in);
		fclose(out);
	}
	else
	{
		printf("Error\n");
	}


	return 0;
}

void tipar_s(uint *stiva, uint nivel)
{
	uint i = 0;
	for(; i <= nivel; i++)
	{
		printf("%u ", stiva[i]);
	}
	printf("\n");
}

bool valid(uint *stiva, uint nivel, uint last)
{
	uint i = 0;
	for(; i < nivel; i++)
	{
		if(stiva[i] == last || stiva[i] > stiva[i + 1])
		{
			return false;
		}
	}

	return true;
}

void submultimi_backtrack_row(uint *stiva, uint nivel, uint n, int **matrix, int r, int c)
{
	uint i = 0;
	for(; i < n; i++)
	{
		stiva[nivel] = i;
		if(valid(stiva, nivel, i))
		{
			int j = 0;
			for(; j <= nivel; j++)
			{
				flip_row(matrix, stiva[j], c);
			}
			int64_t s = sum(matrix, r, c);
			if(s > max)
			{
				max = s;
			}
			j = 0;
			for(; j <= nivel; j++)
			{
				flip_row(matrix, stiva[j], c);
			}

			if((nivel + 1) < n)
			{
				submultimi_backtrack_row(stiva, nivel + 1, n, matrix, r, c);
			}
		}
	}
}

void submultimi_backtrack_col(uint *stiva, uint nivel, uint n, int **matrix, int r, int c)
{
	uint i = 0;
	for(; i < n; i++)
	{
		stiva[nivel] = i;
		if(valid(stiva, nivel, i))
		{
			int j = 0;
			for(; j <= nivel; j++)
			{
				flip_col(matrix, r, stiva[j]);
			}
			int64_t s = sum(matrix, r, c);
			if(s > max)
			{
				max = s;
			}
			j = 0;
			for(; j <= nivel; j++)
			{
				flip_col(matrix, r, stiva[j]);
			}

			if((nivel + 1) < n)
			{
				submultimi_backtrack_col(stiva, nivel + 1, n, matrix, r, c);
			}
		}
	}
}

void flip_row(int **matrix, int k, int m)
{
	int i = 0;
	for(; i < m; i++)
	{
		matrix[k][i] = -matrix[k][i];
	}
}

void flip_col(int **matrix, int n, int k)
{
	int i = 0;
	for(; i < n; i++)
	{
		matrix[i][k] = -matrix[i][k];
	}
}

int64_t sum(int **matrix, int n, int m)
{
	int64_t s = 0;
	int i = 0;
	for(; i < n; i++)
	{
		int j = 0;
		for(; j < m; j++)
		{
			s += matrix[i][j];
		}
	}
	return s;
}

mat **read_matrix(mat rows, mat cols, FILE *from)
{
	mat **matrix = malloc(sizeof(mat *) * rows);
	if(matrix != NULL)
	{
		mat i = 0;
		for(; i < rows; i++)
		{
			mat *line = malloc(sizeof(mat) * cols);
			if(line != NULL)
			{
				mat j = 0;
				for(; j < cols; j++)
				{
					mat t = 0;
					fscanf(from, "%d%*c", &t);
					line[j] = t;
				}
				matrix[i] = line;
			}
			else
			{
				printf("Failed init line: %u\n", i);
			}
		}

		return matrix;
	}
	else
	{
		printf("matrix init error\n");
	}
}

void tipar(mat **matrix, mat rows, mat cols, FILE *where)
{
	mat i = 0;
	for(; i < rows; i++)
	{
		mat j = 0;
		for(; j < cols; j++)
		{
			fprintf(where, "%u ", matrix[i][j]);
		}
		fprintf(where, "\n");
	}
}

void free_matrix(mat **matrix, mat rows)
{
	mat i = 0;
	for(; i < rows; i++)
	{
		free(matrix[i]);
	}
	free(matrix);
}

mat **get_empty(mat rows, mat cols)
{
	mat **matrix = malloc(sizeof(mat *) * rows);
	if(matrix != NULL)
	{
		mat i = 0;
		for(; i < rows; i++)
		{
			mat *line = calloc(cols, sizeof(mat));
			if(line != NULL)
			{
				matrix[i] = line;
			}
			else
			{
				printf("Failed init line: %u\n", i);
			}
		}

		return matrix;
	}
	else
	{
		printf("matrix init error\n");
	}
}