题意:给你一个n*n的01矩阵,让你把这个矩阵中尽量少的0转换成1,使得矩阵每个位置的上下左右四个相邻的数加起来能被2整除,求最少的转换数

首先,n 的规模并不大,最大只有15。但是完全枚举整个矩阵显然是不可能的(2225 ≈ 5 * 1067)。但是我们可以枚举第一行,然后用第一行来算出后面的所有行。

但是,怎么算呢?

先来说下算法。对于每一行,我们通过他上面的两行来决定他的值。如果上面两行得到值为奇数,那么这一行就赋值为 1 ,否则赋值为 0 。 然后与原始矩阵比较,如果是由 1 变 0 那么这种情况是不允许的,于是继续枚举第一行,重新计算后面的。如果是由 0  变 1(或不变) 那么保存下来。最后在计算所有的格子之后,遍历一下就能统计转化数。然后取最小值就可以了。

下面用题目中给的第二组数据来演示一下如何通过上一行来计算下一行。

问题                                        正解

0 0 0                 ==>              0 1 0

1 0 0                 ==>              1 0 1

0 0 0                 ==>              0 1 0

来举例说明。首先我们通过枚举第一行可以达到以下情况

0 1 0
     
     

如下表我们开始通过第一行来计算第二行,对于 x 所在的这一格来说,把这一格当做他上面一格的下面相邻的格子进行计算,于是对于第一行第一列来说,他上下左右相加起来为 1 + x,因为要保证是偶数,所以 x = 1。接着与原矩阵进行比较,是符合题目要求的转化(不变)。保留,继续计算下一个。

0 1 0
x    
     

如下表开始计算第二行第二列,按照上面的方法,计算得出 0 + 0 + x 要为偶数,所以 x = 0。与原数组比较依旧是符合题目要求的。

0 1 0
1 x  
     

如下表计算第二行第三列,同上,得出 1 + x 要为偶数,所以 x  = 1。与原矩阵比较,发现是符合要求的转化(0 变 1)继续。

0 1 0
1 0 x
     

这样第二行就得出来了,是下面这种情况:

0 1 0
1 0 1
     

按照上述方法,可以计算出第三行,来完成这个例子的答案:

0 1 0
1 0 1
0 1 0

最后在说一下枚举第一行的 2 种方法,第一个种自然是直接深度优先搜索(DP)直接进行枚举。第二种可以利用位运算(末尾附上的AC代码采用的方法)进行枚举。因为整数在内存中是用二进制存储的。只要让 s 从 0 开始一直加到 2n-1 – 1 这么大就可以枚举所有的情况。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = + ;
const int INF = ( << ) - ;
int a[N][N], dp[N][N],n; int deal(int s){
memset(dp, , sizeof(dp));
for(int c = ; c < n; c++){
if(s & ( << c)) dp[][c] = ;
else if(a[][c] == ) return INF;
}
for(int r = ; r < n; r ++){
for(int c = ; c < n; c ++){
int sum = ;
if(r > ) sum += dp[r-][c];
if(c > ) sum += dp[r-][c-];
if(c < n) sum += dp[r-][c+];
dp[r][c] = sum % ;
if(dp[r][c] == && a[r][c] == )return INF;
}
}
int ret = ;
for(int r = ; r < n; r ++)
for(int c = ; c < n; c ++)
if(a[r][c] != dp[r][c]) ret++;
return ret;
} int main(){
int T;
scanf("%d", &T);
for(int cas = ; cas <= T; cas ++){
scanf("%d", &n);
for(int r = ; r < n; r ++)
for(int c = ; c < n; c ++)
scanf("%d", &a[r][c]);
int ans = INF;
for(int s = ; s < ( << n); s ++)
ans = min(ans, deal(s));
printf("Case %d: %d\n", cas, ans == INF ? - : ans);
}
return ;
}

【转载】UVa 11464 Even Parity 偶数矩阵的更多相关文章

  1. UVa 11464 Even Parity 偶数矩阵

    给你一个 n * n 的 01 矩阵,现在你的任务是将这个矩阵中尽量少的 0 转化为 1 ,使得每个数的上下左右四个相邻的数加起来是偶数.求最少的转化个数. 首先,n 的规模并不大,最大只有15.但是 ...

  2. UVA.11464 Even Parity (思维题 开关问题)

    UVA.11464 Even Parity (思维题 开关问题) 题目大意 给出一个n*n的01方格,现在要求将其中的一些0转换为1,使得每个方格的上下左右格子的数字和为偶数(如果存在的话),求使得最 ...

  3. 状态压缩+枚举 UVA 11464 Even Parity

    题目传送门 /* 题意:求最少改变多少个0成1,使得每一个元素四周的和为偶数 状态压缩+枚举:枚举第一行的所有可能(1<<n),下一行完全能够由上一行递推出来,b数组保存该位置需要填什么 ...

  4. 【巧妙算法系列】【Uva 11464】 - Even Parity 偶数矩阵

    偶数矩阵(Even Parity, UVa 11464) 给你一个n×n的01矩阵(每个元素非0即1),你的任务是把尽量少的0变成1,使得每个元素的上.下.左.右的元素(如果存在的话)之和均为偶数.比 ...

  5. UVA 11464 Even Parity(递归枚举)

    11464 - Even Parity Time limit: 3.000 seconds We have a grid of size N x N. Each cell of the grid in ...

  6. UVA 11464 Even Parity(部分枚举 递推)

    Even Parity We have a grid of size N x N. Each cell of the grid initially contains a zero(0) or a on ...

  7. UVa 11464 - Even Parity

    解题报告:题目大意有一个N×N的矩阵,矩阵中的元素只有1或0,如果说对于一个矩阵,它的所有的点的上下左右的点的和是偶数,则称这个矩阵为偶数矩阵,现在给你一个任意的矩阵,要求的是如果要把这个矩阵变成偶数 ...

  8. UVA 11464 - Even Parity(枚举方法)

    D Even Parity Input: Standard Input Output: Standard Output We have a grid of size N x N. Each cell ...

  9. UVA 11464 - Even Parity 状态压缩,分析 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

随机推荐

  1. 邮件群发工具(C#版)

    引言 经常会参与组织一些社区活动,涉及到和不同的人进行交流,微信当然是必须的,同样邮件也是一种不可或缺的方式. 一般群发的邮件不是很友好,如果是一对一的,收到邮件的人是不是会比较重视,而且还有他的名字 ...

  2. TXT记事本转换PDF文件

    使用的方式为,读取TXT记事本的内容,然后写入创建的PDF文件. static void Main(string[] args) { const string txtFile = "D:\\ ...

  3. 记录Hibernate的缓存知识

    一.Hibernate缓存的作用 Hibernate是一个持久层框架,Hibernate要经常访问物理数据库.为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能,Hibernate的缓 ...

  4. angularjs onchange

    HTML <div ng-controller="TestCtrl"> <select ng-change="change(x)" ng-mo ...

  5. Effective Java 30 Use Enums instead of int constants

    Enumerated type is a type whose legal values consist of a fixed set of constants, such as the season ...

  6. Effective Java 36 Consistently use the Override annotation

    Principle Use the Override annotation on every method declaration that you believe to override a sup ...

  7. yum 安装包的用法

    最近刚爆出linux下glibc有重大漏洞,修复方案为升级glibc库 RHEL/CentOS下一键即可修复 : sudo yum update glibc .或者如果本地有rpm包 直接 rpm - ...

  8. Hive history date mapping

    Hive history table mapping create table fdl_family as select * from (select 'acc1' as account,'famil ...

  9. javascript原型Prototype

    在javaScript创建对象一文中提到过:用构造函数创建对象存在一个问题即同一构造函数的不同实例的相同方法是不一样的,所以我们用原型把构造函数中公共的属性和方法提取出来进行封装,达到让所有实例共享的 ...

  10. 关于JS获取select值的两种实现方法

    前几天发了一篇关于javascript获取select值的方法,后来发现有另一种实现方法,所以就都发出来比较一下: 方法一:通过获取option标签的value值来确定: <!DOCTYPE h ...