翻硬币:有N(N<=10000)行硬币,每行9个,排成一个N*9的方阵,有的硬币正面朝上,有的则相反。我们每一次可以把一整行或者一整列翻装,请问怎么翻,使得正面朝上的硬币尽可能多。
目前思路:1.一定要把行翻装操作和列翻转操作捆绑起来,称为一次翻转,以保证每一次翻转,正面硬币个数能够增加。
说明:0为正 1为反
初始反面数目为8
11000
11000
00110
00110
00000
一次正翻转以后变成
00111
11000
00110
00110
00000
正面个数减少了,但是此时,通过一个列翻转
00001
00001
00000
00000
00110
反面数目仅为4。
故把行翻转和列翻转捆绑在一起,可保证每一次翻转以后,正面数目有所增加。
思路2:给每一个元素一个行翻转标志位和列翻转标志位,置0为上次翻转操作对该元素不进行修改,反之则上次操作进行了修改,若便利一次整个方阵,所有标志位均为(0,0),程序结束。
现在的具体问题是思考翻转的具体细节!
******************************我是分割线*******************************************************************************************************************************************
有想法了!
一次翻转的定义与上面一致,每做完一次翻转以后,就进行测试。测试内容如下:
上一次结果中,把没有全部为正面的那些行全部翻转,然后按照“使得正面硬币个数有所增长的原则”进行列翻转(参考上例)。观测正面朝上硬币个数,若增加,则把初始方阵状态置换为测试方阵状态,否则,初始方阵保持不变。
然后进行下列操作:(翻转前要检测标志位)
1. 把上一次结果的方阵中正面朝上少于反面朝上的行翻转过来;
2. 把上一次结果的方阵中正面朝上少于反面朝上的列翻转过来;
3. 统计并测试。
程序结束标志:标志为均为(0,0).
算法有可能存在的缺陷:在进行测试的时候,全0的行是不进行转置的,这可能会出现问题。