UVA.11464 Even Parity (思维题 开关问题)
UVA.11464 Even Parity (思维题 开关问题)
题目大意
给出一个n*n的01方格,现在要求将其中的一些0转换为1,使得每个方格的上下左右格子的数字和为偶数(如果存在的话),求使得最小的转换的个数。
最先想到的是枚举每个方格的状态,非0即1,那么就有2^(n*n)种情况,可见数量之大,必定超时。那么就必须要转换思路。
不难看出这是一个开关问题,就是说可以根据一行的数据,推算出下一行的数据,然后顺次推算出整个格子的数据,之后再来看改变了多少的01序列,求出最小的结果。(稍后会演示推算的算法)。
那么首先就是要枚举第一行的各种情况,这个不难实现。由于题目要求很局限,只是01序列,我们可以采用二进制的方法来依次枚举:
第一行有n个格子,每个格子有2种状态,故需要枚举2^n次。不妨我们先让n为3,看看是如何枚举的。
外层循环是 for i = 0 to (2^3-1)
i = 0 00000000
i = 1 00000001
i = 2 00000010
i = 3 00000011
i = 4 00000100
i = 5 00000101
i = 6 00000110
i = 7 00000111
不难看出 上面的式子中,后3位的情况,正好是我们要枚举的情况。但是我们不能直接取后三位,要想办法,于是问题抓换成:什么时候将某一位(二维数组的某一元素)赋值为1
由于一次只能对1位(二维数组中的一个元素)赋值,我们还需要一层循环, for j = 0 to (n-1) ,再观察下面的式子:
i = 0,j = 0 时 i&(1 << j) =00000000 即为 0
i = 0,j = 1 时 i&(1 << j) = 00000000 即为 0
i = 0,j = 2 时 i&(1 << j) = 00000000 即为0
上面的3式子,可以看做完成了000的赋值。
i = 1,j = 0 时 i&(1 << j) = 00000001 即为1
i = 1,j = 1 时 i&(1 << j) = 00000000 即为 0
i = 1,j = 2 时 i&(1 << j) = 00000000 即为 0
上面的3个式子,可以看做是完成了100的赋值
i = 2,j = 0 时 i&(1 << j) = 00000000 即为 0
i = 2,j = 1 时 i&(1 << j) = 00000000 即为 1
i = 1,j = 2 时 i&(1 << j) = 00000000 即为 0
上面的3个式子,可以看做是完成了010的赋值
……
以此类推,不难看出,这样的2重循环,就完成了对第一行格子的枚举。当然还要注意题目并不允许将1换成0,如果有这样的情况出现,那么要跳过。
现在完成了第一行的枚举。就要根据性质来分别计算第1到n-1行的数据了。依据的性质就是题目中的使得每个方格的上下左右格子的数字和为偶数(如果存在的话),有些读者到此处已经可以大致的写出程序了。大概的算法叙述如下:
我们要算第二行第一列的格子是0还是1,然是并不能直接对这个格子计算,因为他的右边我们还不确定。所以要根据他上一行的格子来计算,由于上一行的格子是在第一行,也就是说他没有上方和左方的格子(这里指的是第一行第一列的格子,若是中间部分的格子,那么只是没有上面的格子,若是第一行最右列的格子,那么他就没有右边和上边的格子),那么求和只需要求右面和下面的格子。而下面的格子又是待求的格子,那么只需要让这个和对2取模,就是这个格子的答案。当然依旧要注意题目并不允许将1换成0。如果有的话,还是要终止这次计算。
(若还有些许不明白,建议看这篇博文:传送门 里面介绍的十分详细)
最后分别求出剩下几行的格子,对比原先的数据,看看改变了多少个01序列。 别忘了上面我们写了一个for循环的枚举,在这么多的情况下,取最小即可,若没有则说明无法打成题目要求,输出-1即可。
代码总览
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define nmax 20
#define INF 0x3f3f3f3f
using namespace std;
int a[nmax][nmax],b[nmax][nmax],n;
int check(int t)
{
memset(b,0,sizeof(b));
//根据传入的参数t来枚举第一行
for(int i = 0; i<n ;++i){
if(t & (1<<i) ) b[0][i] = 1;
else if(a[0][i] == 1) return INF;
}
//依次确定第1至n-1行的内容
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;
// 题目中不允许把1 变成 0
if(a[i][j] == 1 && b[i][j] == 0) return INF;
}
}
int ans = 0;
for(int i = 0; i<n; ++i)
for(int j = 0; j<n; ++j)
if(a[i][j] != b[i][j])
ans++;
return ans;
}
int main()
{
int T;
scanf("%d",&T);
for(int cas = 0; cas <T ;cas++){
//int n;
scanf("%d",&n);
for(int i = 0; i<n;++i)
for(int j = 0; j<n; ++j)
scanf("%d",&a[i][j]);
int ans = INF;
for(int i = 0 ; i < (1<<n);++i){
ans = min(ans, check(i));
}
printf("Case %d: ",cas+1);
if(ans == INF) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
UVA.11464 Even Parity (思维题 开关问题)的更多相关文章
- UVA.11636 Hello World! (思维题)
UVA.11636 Hello World! (思维题) 题意分析 这题挺水的,还是错了几发. QWQ. 有一个同学打了一行hello world,现在他想打n行hello world,请问最少复制粘 ...
- 状态压缩+枚举 UVA 11464 Even Parity
题目传送门 /* 题意:求最少改变多少个0成1,使得每一个元素四周的和为偶数 状态压缩+枚举:枚举第一行的所有可能(1<<n),下一行完全能够由上一行递推出来,b数组保存该位置需要填什么 ...
- 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
解题报告:题目大意有一个N×N的矩阵,矩阵中的元素只有1或0,如果说对于一个矩阵,它的所有的点的上下左右的点的和是偶数,则称这个矩阵为偶数矩阵,现在给你一个任意的矩阵,要求的是如果要把这个矩阵变成偶数 ...
- 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(枚举方法)
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 ...
- 【转载】UVa 11464 Even Parity 偶数矩阵
题意:给你一个n*n的01矩阵,让你把这个矩阵中尽量少的0转换成1,使得矩阵每个位置的上下左右四个相邻的数加起来能被2整除,求最少的转换数 首先,n 的规模并不大,最大只有15.但是完全枚举整个矩阵显 ...
- UVa 11464 Even Parity 偶数矩阵
给你一个 n * n 的 01 矩阵,现在你的任务是将这个矩阵中尽量少的 0 转化为 1 ,使得每个数的上下左右四个相邻的数加起来是偶数.求最少的转化个数. 首先,n 的规模并不大,最大只有15.但是 ...
随机推荐
- hdu1171Big Event in HDU(01背包)
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- CSS选择器语法&示例
CSS3 选择器 在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素. "CSS" 列指示该属性是在哪个 CSS 版本中定义的.(CSS1.CSS2 还是 CSS3.) ...
- python 中的reload(sys)
import sys reload(sys) sys.setdefaultencoding('utf-8') #python2中的使用方法 #重新载入 sys 模块,并设置默认编码为 utf8 & ...
- Java异常层次结构
1. 如果是不可查异常(unchecked exception),即Error.RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在 ...
- Java进阶知识点:更优雅地关闭资源 - try-with-resource
一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制, ...
- Learning Spatial-Temporal Regularized Correlation Filters for Visual Tracking---随笔
Learning Spatial-Temporal Regularized Correlation Filters for Visual Tracking DCF跟踪算法因边界效应,鲁棒性较差.SRD ...
- 【机器学习】线性回归python实现
线性回归原理介绍 线性回归python实现 线性回归sklearn实现 这里使用python实现线性回归,没有使用sklearn等机器学习框架,目的是帮助理解算法的原理. 写了三个例子,分别是单变量的 ...
- 在本地电脑使用远程服务器的图形界面——包括 MATLAB、PyCharm 等各种软件
在用本地电脑连接远程服务器的时候,大部分时候只能用命令行来操作.虽然可以 在本地电脑用 PyCharm 进行远程调试.在本地电脑远程使用服务器的 Jupyter Notebook.Ubuntu 和 W ...
- 一些容易记混的c++相关知识点
一些容易记混的c++相关知识. 截图自:<王道程序员面试宝典>
- SGU 176 Flow construction(有源汇上下界最小流)
Description 176. Flow construction time limit per test: 1 sec. memory limit per test: 4096 KB input: ...