uva 11464 - Even Parity(暴力枚举)

题目大意:给出一个由0和1组成的矩阵,修改最少的0变成1,使得矩阵中每个位置的上下左右存在的情况下,和为偶数,无解输出-1。


解题思路:枚举,但是枚举所有位置的话,n最大为15,有2^255,肯定超时。但是不难发现,如果确定了i行,那么i + 1行肯定是确定。所以只要枚举第一行就可以了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int INF = 0x3f3f3f3f;
int A[20][20], B[20][20], n;

int solve(int s) {
	memset(B, 0, sizeof(B));
	for (int i = 0; i < n; i++)
		if(s & (1 << i)) 
			B[0][i] = 1;
		else if (A[0][i] == 1)
			return INF;

	for (int i = 1; i < n; i++)
		for (int j = 0; j < n; j++) {
			int sum = 0;
			if (i > 1)	
				sum += B[i-2][j];
			if (j > 0)
				sum += B[i-1][j-1];
			if (j < n - 1)
				sum += B[i-1][j+1];

			B[i][j] = sum % 2;
			if (A[i][j] == 1 && B[i][j] == 0)
				return INF;
		}

	int cnt = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (A[i][j] != B[i][j])
				cnt++; 
	return cnt;
}

int main() {
	int T, cnt = 0;
	scanf("%d", &T);
	while (T--) {
		int ans = INF;
		scanf("%d", &n);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				scanf("%d", &A[i][j]);
		for (int i = 0; i < (2 << n); i++)
			ans = min(ans, solve(i));

		if (ans == INF)
			ans = -1;
		printf("Case %d: %d\n", ++cnt, ans);
	}
	return 0;
}


你可能感兴趣的:(uva 11464 - Even Parity(暴力枚举))