uva 11464 B - Even Parity 【二进制枚举】

题意:给定一个n*n的矩阵,由0 1组成,每次操作可以将0变成1,问,最少需要多少次操作可以使每个数周围数之和为偶数。

思路:枚举第一行可能有的所有情况,再根据每种情况计算出剩下行的排列存入临时数组,每次操作之和就是临时数组和原数组不同的值总和,取所有情况之和中的最小值输出即可。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 20;
int map[maxn][maxn],n;
int dfs(int m)
{
	int i,j;
	int vis[maxn][maxn];
	memset(vis,0,sizeof(vis));
	for(i = 0; i < n; i ++)
		if(m&(1<<i))//枚举第一行为m时,每一列的情况,同时为1时存入临时数组 
			vis[0][i] = 1;
		else if(map[0][i] == 1)//map第i列的值为1而枚举的m第i列为0时,不符合条件,退出 
			return inf;
	for(i = 1; i < n; i ++)
	{
		for(j = 0; j < n; j ++)
		{
			int sum = 0;
			if(i > 1)
				sum += vis[i-2][j];
			if(j > 0)
				sum += vis[i-1][j-1];
			if(j < n-1)
				sum += vis[i-1][j+1];
			vis[i][j] = sum%2;
			if(vis[i][j] == 0&&map[i][j] == 1)//1不能转变为0,也不符合该条件 
				return inf;
		}
	}
	int ans = 0;	
	for(i = 0; i < n; i ++)
		for(j = 0; j < n; j ++)
			if(vis[i][j]!=map[i][j])
				ans ++;
	return ans;
}

int main()
{
	int t,ans,t2;
	int i,j;
	scanf("%d",&t);
	t2 = 0;
	while(t--)
	{
		scanf("%d",&n);
		for(i = 0; i < n; i ++)
			for(j = 0; j < n; j ++)
				scanf("%d",&map[i][j]);
		ans = inf;
		for(i = 0; i < (1<<n); i ++)//枚举第一行可能的状态 
			ans = min(ans,dfs(i));//尽量取小值 
		printf("Case %d:",++t2);
		if(ans == inf)
			printf(" -1\n");
		else
			printf(" %d\n",ans);
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值