【问题标题】:How to find entry of each a(i, j) in n*n matrix where n<=900 and a(i,j)=0 or a(i, j)=1?如何在n <= 900且a(i,j)= 0或a(i,j)= 1的n * n矩阵中找到每个a(i,j)的条目?
【发布时间】:2020-06-09 13:04:48
【问题描述】:

假设我给了 n 基本上 n*n 矩阵,开始时全为零。

并且给出了与每一行和每一列相关的总和。

例如。 n=4

矩阵:

0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0

给定行总和:2, 2, 1, 1

给定列总和:2, 0, 2, 2

所以输出矩阵应该是这样的:

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

总有解决方案存在。 所以对于n=40&lt;=rowsum&lt;=4 and 0&lt;=columnsum&lt;=4

【问题讨论】:

  • 到目前为止您尝试过什么?这么好的问题因缺乏努力而被关闭,这将是一种耻辱。
  • 输出矩阵应该是那个解决方案吗?还有更多的解决方案,例如1010 0011 0001 1000
  • @harold 任何解决方案都应该没问题,只要它匹配给定的输入
  • @NitinSinghal 请多解释一下你的问题。
  • 总是有可能吗?

标签: java algorithm


【解决方案1】:

你可以用贪婪的方法解决这个问题。

while not filled:
    find biggest unfilled row:
        fill in putting 1s in columns with largest sums

在你的情况下,你开始:

    2 2 0 2
  ----------
2 | _ _ _ _
2 | _ _ _ _
1 | _ _ _ _
1 | _ _ _ _

填写我们得到的行之一:

    1 1 0 2
  ----------
2 | _ _ _ _
  | 1 1 0 0
1 | _ _ _ _
1 | _ _ _ _

填写另一个:

      1   1
  ----------
  | 1 0 0 1
  | 1 1 0 0
1 | _ _ _ _
1 | _ _ _ _

另外两个也可以类似填写:

  ----------
  | 1 0 0 1
  | 1 1 0 0
  | 0 1 0 0
  | 0 0 0 1

假设行值的总和与列值的总和匹配,并且所有这些值都匹配0 &lt;= value &lt;= n,则此过程将始终有效。


更新:正如 cmets 中所指出的,其他方式可能不存在解决方案。这可以通过您尝试填充一行并且没有足够的列来填充它的事实来检测。

但是,如果遇到这样的障碍,那就没有办法了。

【讨论】:

  • ... 或相反的方法,使用最小和和零
  • 最后一句可能需要额外的假设“[...] 并且总是存在至少一个解决方案,[...]”,因为例如“02”乘以“02”是无法解决。
  • 这是一个我认为应该很好用的算法,在立方时间内。不禁想知道它是否可以在二次方中完成。
  • ... 除非修改答案以说明此答案中的方法也可用于确定解决方案是否存在,在这种情况下,我以前的评论是无关紧要的告诉。
  • @MelvinWM 好点!如果这失败了,那么就没有解决方案。但你想到了一种方法,我没有错过任何解决方案。
【解决方案2】:

Btilly 的回答对您有用。不过可以改进。您可以通过按降序对它们进行排序来进行预处理,而不是每次都查找总和最大的行和列,但保留它们的原始位置很重要。你可以使用一个简单的类:

class SortedRow {
    int val;
    int originalIndex;
    public SortedRow(val, originalIndex) {
        this.val = val;
        this.originalIndex = originalIndex;
    }
}

然后对它们进行排序(rowVals 和 colVals 是具有所需总和的数组):

public static void preprocess(int[] rowVals, int[] colVals){
    SortedRow[] rows = new SortedRow[n];
    SortedRow[] cols = new SortedRow[n];
    for (int i = 0; i < n; i++) {
        rows[i] = new SortedRow(rowVals[i], i);
        cols[i] = new SortedRow(colVals[i], i);
    }
    // Sort both arrays by val with some sorting algorithm of your choice - in descending order!
}

现在您可以像 Btilly 建议的那样以贪婪的方法开始填充 nxn 矩阵,但您不必每次都寻找最大的矩阵 - 您已经有了它。用新类的originalIndex 字段填写。

它将最坏情况的运行时间从三次变为二次:预处理运行在 O(nlogn) 中,如果您对 n 的值有一些先验知识,甚至可以是线性的。填写矩阵在 O(n^2) 中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 2022-01-13
    相关资源
    最近更新 更多