题目描述 Description

给你一个n*n的01矩阵(每个元素非0即1),你的任务是把尽量少的0变成1,使得每个元素的上、下、左、右的元素(如果存在的话)之和均为偶数。如图所示的矩阵至少要把3个0变成1,最终如图所示,才能保证其为偶数矩阵。

 输入输出格式 Input/output
输入格式:
输入的第一行为数据组数T(T<30)。每组数据的第一行为正整数n(1 < n < 15);接下来的n行每行包含n个非0即1的整数,相邻整数间用一个空格隔开。
输出格式:
对于每组数据,输出被改变的元素的最小个数。如果无解,应输出-1。
 输入输出样例 Sample input/output
样例测试点#1
输入样例:

0 0 0

1 0 0

0 0 0

输出样例:
3
 
思路:这道题很经典,经典的枚举也有DP的意味在里面,这里我把书上的思路详细化。
书上谈到:抛弃枚举每个数字的方法,这样很大,大概2255这么多的情况,很大,难以接受,可以考虑枚举第一行,这样有215种可能,是可行的,根据第一行算出第二行,以此类推到第n行,时间复杂度降为O(2n×n2)
点石成金罢了,下面来说说如何具体的做到:
将样例的第一行:
0 0 0
可以通过枚举变成
0 1 0
这样第一行就确定下来了,这时候考虑第二行:
0 1 0
α
考虑一下第一行第一列的0,它的上下左右加和=α+1,那么这时候要保证是偶数,即(α+1)%2==0,所以α=1,这时候看看这个α可不可以由原矩阵A的这个位置的数变化而来(即0→1),合法,此时记上1。
0 1 0
1 α
同样计算第一行第二列,(0+α+0)%2==0,α=0,比较原矩阵,合法,记上0。
0 1 0
1 0 α
同上,合法变换矩阵为:
0 1 0
1 0 1
最终执行完:
0 1 0
1 0 1
0 1 0
 
大致的思路就是这样,要注意的是一些细节之处,比如位运算简化,这样可以使代码简洁很多且运算方便
 
代码如下(书上copy下来且加了点注释的):
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. const int MAXN=;
  6. const int INF=;
  7. int A[MAXN][MAXN],B[MAXN][MAXN];
  8. int n;
  9. int min(int a,int b)
  10. {
  11. return a>b?b:a;
  12. }
  13. int check(int s)
  14. {
  15. memset(B,,sizeof(int));
  16. for(int c=;c<n;c++)//枚举第一行
  17. {
  18. if(s&(<<c)) B[][c]=;
  19. else if(A[][c]==) return INF;//不能把1变成0,直接返回
  20. }
  21. for(int r=;r<n;r++)//从第二行开始依次筛查
  22. {
  23. for(int c=;c<n;c++)
  24. {
  25. int sum=;//表示上左右三个元素的和
  26. if(r>) sum+=B[r-][c];
  27. if(c>) sum+=B[r-][c-];
  28. if(c<n-) sum+=B[r-][c+];
  29. B[r][c]=sum%;
  30. if(A[r][c]==&&B[r][c]==) return INF;//违法,不能把1变为0
  31. }
  32. }
  33. int cnt=;
  34. for(int r=;r<n;r++)
  35. {
  36. for(int c=;c<n;c++)
  37. {
  38. if(A[r][c]!=B[r][c]) cnt++;
  39. }
  40. }
  41. return cnt;
  42. }
  43. int main()
  44. {
  45. int r,c;//行、列
  46. int i,j;
  47. int T;
  48. int ans=INF;//初始化为最大值
  49. scanf("%d",&T);
  50. while(T)
  51. {
  52. ans=INF;
  53. scanf("%d",&n);
  54. for(i=;i<n;i++)
  55. {
  56. for(j=;j<n;j++)
  57. {
  58. scanf("%d",&A[i][j]);
  59. }
  60. }
  61. for(int s=;s<(<<n);s++)//1<<n等于2^n,不用pow,比较方便
  62. {
  63. ans=min(ans,check(s));//不断更新最小ans
  64. }
  65. if(ans==INF) ans=-;//没找到答案
  66. printf("%d %d\n",T,ans);
  67. T--;
  68. }
  69. return ;
  70. }

偶数矩阵 Even Parity,UVa 11464的更多相关文章

  1. Java实现偶数矩阵(Even Parity, UVa 11464)

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

  2. Even Parity UVA - 11464 (枚举)

    从来没有觉得枚举有多费脑子的.但是这道题还是很香的. 思路:就是非常简单的枚举啦.   从一般的枚举开始考虑.一般的做法就是在所有的格子中有两种状态1, 0. 而一共有225个格子,所有一共要枚举的情 ...

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

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

  4. UVA 11464 偶数矩阵

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

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

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

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

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

  7. 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 ...

  8. UVa 11464 - Even Parity

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

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

    题意:给你一个n*n的01矩阵,让你把这个矩阵中尽量少的0转换成1,使得矩阵每个位置的上下左右四个相邻的数加起来能被2整除,求最少的转换数 首先,n 的规模并不大,最大只有15.但是完全枚举整个矩阵显 ...

随机推荐

  1. Qt Creater-特殊注释TODO,FIXME

    简述 TODO: + 说明: 如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会简略说明. FIXME: + 说明: 如果代码中有该标识,说明标识处代码需要修正,甚至代码是错误的 ...

  2. JVM 初始化阶段的重要意义分析

    1.创建一个Mytest6类和Singleton类 public class MyTest6 { public static void main(String[] args) { Singleton ...

  3. return语句——学习笔记

    return,可以提前结束其所在函数. 函数内不写,会自动加上return. 非引用返回: 引用返回:a=3,b=3 注意事项: 两种修改字符串某一位置值的方式:

  4. Flutter Drawer 侧边栏、以及侧边栏内 容布局

    Flutter Drawer 侧边栏 在 Scaffold 组件里面传入 drawer 参数可以定义左侧边栏,传入 endDrawer 可以定义右侧边 栏.侧边栏默认是隐藏的,我们可以通过手指滑动显示 ...

  5. 安装mysql报错:Can't find messagefile '/usr/share/mysql/english/errmsg.sys'和/usr/bin/mysqladmin: error while loading shared libraries: libmysqlclient.so.16: cannot open shared object file: No such file or

    使用yum安装mysql服务端: [root@centos ~]# yum -y install mysql-server Loaded plugins: fastestmirror, securit ...

  6. Spring cloud微服务安全实战-4-6搭建OAuth2资源服务器

    认证服务器已经搭建好了. 可以通过认证服务器拿到令牌 下面改造订单服务,让它可以用这个令牌. 争对订单服务要做三个事, 1.让订单服务知道它自己是Oauth协议里面的资源服务器.,它知道这个事后,它才 ...

  7. hadoop记录-flink测试

    1.启动集群 bin/start-cluster.sh 2.jps查看进程 3.打开网页端(192.168.66.128:8081) 4.造数据:nc -lk 9000 5.执行./bin/flink ...

  8. 123457123456#0#----com.tym.ErTongFanPai20--前拼后广--儿童FanPai_tym

    com.tym.ErTongFanPai20--前拼后广--儿童FanPai_tym

  9. C#中 [], List, Array, ArrayList 區別

    [] 是針對特定類型.固定長度的.List 是針對特定類型.任意長度的.Array 是針對任意類型.固定長度的.ArrayList 是針對任意類型.任意長度的.Array 和 ArrayList 是通 ...

  10. 05点睛Spring MVC 4.1-服务器端推送

    转发:https://www.iteye.com/blog/wiselyman-2214626 5.1 服务器端推送 SSE(server send event)是一种服务器端向浏览器推送消息的技术, ...