在一个9*9的表格里,每个格子只能填0或1,现在问最少经过多少次转换(把0换成1或把1换成0),使得这9*9的表格满足每行、每列和每3*3(共9个)的1的个数为偶数!
此题乍一看,9*9的格子,每个点有两种状态,要搜索的话,肯定会超时的!
问题的关键就在于不能一个位置一个位置的尝试转换,要整行整行的处理。为什么这样说?还是来看样例吧!
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
首先约定某行、某列或某块的1的个数是奇数或偶数个,简称为某行、某列或某块为奇或为偶。
先看第0行,显然第0行为偶,此时需不需要对第1行处理呢?答案是:不需要!为什么呢?假若要处理的话,则一定会处理偶数个列,若要是把这偶数个列的处理放在下一行,一定不会影响下一行的奇偶性,所以在这里我们无需处理。
再看第1行,显然第1行也为偶,如上,也无需处理!
再看第2行,显然第2行也为偶,如果按上面的处理,那也不需要处理了!这行不行?那可不行!为什么?因为这一行不仅是独立的行,而且还还是最上面的三个块的结果位置!所以在这一行即要处理行,也要处理块!
对于块结束的行,先处理每一块,块的处理也如同行一样,块为偶则无需处理,块为奇,则任选一列(要搜索了),并且改变列的奇偶性!(行的不需要改,因为必然会使得这一行为偶,否则这个数据就是错的!)
再看第3行,为偶,不处理;
再看第4行,为奇,此时从9列中任选一列(搜索下去),并要修改所选列和相应块的奇偶性,继续下去!
5行如同2行处理,6、7如同0行处理。
对于最后一行,如果2行一样先处理块,最后检查还几列为奇,统计总数,每列都需要处理一个!这里我还检查总数是否为奇,若为奇,则方案有错!好像这个判断没有必要!感觉好像一定是偶数!(没仔细想清楚)!
这样找到一种方案,记录出其处理的个数!就这样继续搜索下一个!这里有一个重要的剪枝,当前处理的数与已有方案的最小处理数比较,若大于等于这个最小数,则直接回溯!
其实本题的想法就是:每一行都是行的结束,处理某行,下面行的处理就不会影响到上面行!当遇到块结束时,必需处理当前结束的块,因为下面的处理也不会影响到上面的块!而由于列到最后才结束,即它最后处理!