算法将一个硬币矩阵转移到另一个硬币矩阵

时间:2012-02-03 14:51:59

标签: c++

说明
 桌面上有m * n(m <= 100,n <= 100)个硬币,形成m行n列硬币矩阵。每枚硬币面向上或面向后,由0或1表示。

游戏规则是:

(1)每次,你都可以反转一排硬币   (2)每次,你都可以交换两列。

对象
  从初始矩阵 - &gt;目标矩阵

输入:
   1. k测试大小的计数
   2.行数和列数
   3.初始矩阵和目标矩阵的数量

输出    从初始矩阵到目标矩阵的最小步骤,如果无法从初始矩阵转移到目标,则输出-1。

示例输入

2
4 3
1 0 1
0 0 0
1 1 0
1 0 1

1 0 1
1 1 1
0 1 1
1 0 1

4 3
1 0 1
0 0 0
1 0 0
1 1 1

1 1 0
1 1 1
0 1 1
1 0 1

示例输出

2

-1

我编写了一个解决方案:mysolution.cc,它列举了所有可能性,哪些是正确的但速度太快,你能否提供正确但快速的解决方案。

感谢。

2 个答案:

答案 0 :(得分:1)

我会给你一些想法。你逐行比较。如果第一个矩阵的第i行与第二个矩阵的第i行中的第1行具有相同的数量 - 则不反转。如果第一个矩阵的第i行与第二个矩阵的第i行中的0具有相同的1,则必须反转。如果这两者都不成立,则没有解决方案。这完全是为了反转。

现在所有列都相同但顺序不同(第二个矩阵具有来自第一个矩阵的置换列)。如果列不是彼此的排列 - 返回-1。这个问题等于找到将一个排列转换为另一个排列的最小交换次数。

答案 1 :(得分:1)

行始终保持在同一位置,因此,如果行rk开头,则始终会有k个或columns - k

    每行
  1. ,检查count_of_ones(initial,row) == count_of_ones(target,row)是否正确,否则检查是否count_of_ones(initial,row) = columns - count_of_ones(target,row),如果是,则翻转行,否则输出-1。正如@maniek所指出的那样,只有一半的列包含那些列并不容易。必须在步骤2中处理此类行以尝试形成所需的列。
  2. 对于每列,计算目标和工作矩阵中的1的数量(在适当地翻转行之后)。如果计数序列不是彼此的排列,则输出-1,否则尝试查找将工作转换为目标的列的排列(工作和目标之间相同的任何列必须保持固定)。如果不可能,请输出-1,否则找到实现该排列所需的最小交换次数。