问题在于:我给了一个类似
的矩阵输入:
1 1 1
1 1 1
1 1 1
在每一步,我需要找到一个1和0的“第二”矩阵,同一行或列上没有两个1。然后,我将从原始矩阵中减去第二个矩阵。我将重复这个过程,直到我得到一个全0的矩阵。此外,我需要采取尽可能少的步骤。
我需要在O(n)时间内打印所有“第二”矩阵。在上面的例子中,我可以通过按顺序减去这三个矩阵,在3个步骤中得到空矩阵:
预期产出:
1 0 0
0 1 0
0 0 1
0 0 1
1 0 0
0 1 0
0 1 0
0 0 1
1 0 0
我编写了一个尝试,我在其中找到第一个最大值,并根据该值的索引创建第二个矩阵。但是对于上面的输入我得到4个输出矩阵,这是错误的:
我的输出:
1 0 0
0 1 0
0 0 1
0 1 0
1 0 0
0 0 0
0 0 1
0 0 0
1 0 0
0 0 0
0 0 1
0 1 0
我的解决方案适用于大多数测试用例,但对于上面给出的测试用例失败了。有人可以给我一些关于如何进行的指示,或找到一种保证最优性的算法吗?
有效的测试用例:
输入:
0 2 1
0 0 0
3 0 0
输出
0 1 0
0 0 0
1 0 0
0 1 0
0 0 0
1 0 0
0 0 1
0 0 0
1 0 0
答案 0 :(得分:1)
每个行/列的求和并取这些总和中的最大值,可以得到减少到空矩阵所需的最佳矩阵减法次数。
例如:
1 2 4 0 = 7
2 2 0 1 = 5
0 0 1 0 = 1
3 0 2 1 = 6
= = = =
6 4 7 2
这意味着该矩阵将采用7个最佳减法来清空。
我相信从此向后计数并从具有该值的列/行中删除将解决您的问题(我不确定选择这些的有效方法 - 暴力?)。
您还可以使用以前的方法删除多余的元素。
例如(使用上述矩阵)。
步骤7:
我们必须从第1行和第1行中减去第3栏。
0 0 1 0
0 0 0 0
0 0 0 0
0 0 0 0
解决这个问题,现在我们可以使用您之前的方法删除“奖励”元素。
0 0 1 0
1 0 0 0
0 0 0 0
0 0 0 1
现在再次应用每行/列的总和,然后继续下一步。
第6步:
1 2 3 0 = 6
1 2 0 1 = 4
0 0 1 0 = 1
3 0 2 0 = 5
= = = =
5 4 6 1
下一个减法:
0 0 1 0
0 1 0 0
0 0 0 0
1 0 0 0
等等。
注意:对于“全1”矩阵,这仍然不能很好地工作,因为你会遇到从每一行和每列中选择1的问题(与你在例子中的做法相同)。
但有人可以扩展我的解决方案。
答案 1 :(得分:0)
1)如果您想要做的只是遍历矩阵中的所有元素......
2)然后你所要做的就是循环for (int i=0; i < rows*cols; i++) {}
......
3)这样的循环是 ALREADY O(n)(即它与矩阵中的#/元素一起线性增加)
答案 2 :(得分:0)
设行数=列数= N
for iteration=1:N
for row=1:N
cell(row,(row+iteration)%N) := 0
迭代次数为N.在每次迭代中,N将被更改为0
答案 3 :(得分:0)
我不完全确定这是否是您所追求的,但是您是否可以创建可用列的列表并将它们标记为每次迭代使用。
例如:
repeat until an empty matrix
mark all columns as available
for each row
find the maximum value in all available columns and store it's coordinates
mark that column as unavailable
print, decrement and clear the list of stored coordinates
这不起作用,但确实显示了用户1459032正在使用的算法。
答案 4 :(得分:0)
我很确定这是exact cover problem的某种变体,已知它是NP完全的。您提出的算法是一个简单的贪心解决方案。贪婪解决方案的问题在于它们通常能够很好地说服你贪婪是好的,然后突然让你高高兴兴地寻找更好的解决方案。 (例如,考虑全球经济。)无论如何,Knuth的Dancing Links技术是解决问题的标准方法(确切的集合覆盖,而不是全球经济)。