【转载】UVa 11464 Even Parity 偶数矩阵

题意:给你一个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 偶数矩阵的更多相关文章
- UVa 11464 Even Parity 偶数矩阵
给你一个 n * n 的 01 矩阵,现在你的任务是将这个矩阵中尽量少的 0 转化为 1 ,使得每个数的上下左右四个相邻的数加起来是偶数.求最少的转化个数. 首先,n 的规模并不大,最大只有15.但是 ...
- UVA.11464 Even Parity (思维题 开关问题)
UVA.11464 Even Parity (思维题 开关问题) 题目大意 给出一个n*n的01方格,现在要求将其中的一些0转换为1,使得每个方格的上下左右格子的数字和为偶数(如果存在的话),求使得最 ...
- 状态压缩+枚举 UVA 11464 Even Parity
题目传送门 /* 题意:求最少改变多少个0成1,使得每一个元素四周的和为偶数 状态压缩+枚举:枚举第一行的所有可能(1<<n),下一行完全能够由上一行递推出来,b数组保存该位置需要填什么 ...
- 【巧妙算法系列】【Uva 11464】 - Even Parity 偶数矩阵
偶数矩阵(Even Parity, UVa 11464) 给你一个n×n的01矩阵(每个元素非0即1),你的任务是把尽量少的0变成1,使得每个元素的上.下.左.右的元素(如果存在的话)之和均为偶数.比 ...
- 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 ...
- 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 ...
- UVa 11464 - Even Parity
解题报告:题目大意有一个N×N的矩阵,矩阵中的元素只有1或0,如果说对于一个矩阵,它的所有的点的上下左右的点的和是偶数,则称这个矩阵为偶数矩阵,现在给你一个任意的矩阵,要求的是如果要把这个矩阵变成偶数 ...
- UVA 11464 - Even Parity(枚举方法)
D Even Parity Input: Standard Input Output: Standard Output We have a grid of size N x N. Each cell ...
- UVA 11464 - Even Parity 状态压缩,分析 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
随机推荐
- openstack问题汇总
No tenant network is available for allocation. No tenant network is available for allocation. 这个问 ...
- 【故障处理】ORA-30012的解决过程
[故障处理]ORA-30012的解决过程 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O ...
- CentOS 7 安装Docker
1.安装前检查: a.内核版本 uname -a b.检查Device Mapper ls -l /sys/class/misc/device-mapper 2.安装Docker: a.更新系统包到最 ...
- 续Gulp使用入门-综合运用>使用Gulp构建一个项目
这是我的文件目录结构图 下面是我gulpfile.js的配置 'use strict' var gulp=require('gulp'); var gutil=require('gulp-util' ...
- avahi-daemon启动失败-解决方法-linux
avahi-daemon是一种Linux操作系统上运行在客户机上实施查找基于网络的Zeroconf service的服务守护进程. 该服务可以为Zeroconf网络实现DNS服务发现及DNS ...
- Java基础の第一弹
一.虚拟机的工作机制 (1) :通过 ClassLoader 寻找和装载 class 文件 (2) :解释字节码成为指令并执行,提供 class 文件的运行环境 (3) :进行运行期间垃圾回收 (4) ...
- TYVJ1288 飘飘乎居士取能量块 -SilverN
描述 9月21日,今天是pink的生日,飘飘乎居士当然要去别人的领土大闹一番啦! 为了收集更多的能量到pink家大闹,飘飘乎居士准备从后花园中取出自己多年积攒的p个能量块.后花园一共被划分n个地 ...
- 边工作边刷题:70天一遍leetcode: day 84-2
要点:这题是combination的应用,从左向右想比从右向左容易. 因为有结果从小到大的要求,暗示用combintion而不是permutation 其实就是从小到大验证因子,每个因子和其对称因子立 ...
- 2014 Super Training #1 C Ice-sugar Gourd 模拟,扫描线
原题 HDU 3363 http://acm.hdu.edu.cn/showproblem.php?pid=3363 给你一个串,串中有H跟T两种字符,然后切任意刀,使得能把H跟T各自分为原来的一半. ...
- 基础KMP两道
1. HDU 1711 Number Sequence 代码: #include <iostream> #include <cstdio> #include <cstri ...