问题是:
在一个尺寸为m x n的神奇矩形中,每个条目都是行和列的异或,索引为零。示例(8 x 5):
0 1 2 3 4 5 6 7
1 0 3 2 5 4 7 6
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
4 5 6 7 0 1 2 3
我需要找到每个项目的总和,然而,暴力强迫将不工作的投入范围在100万美元。
我目前的工作:
我发现,对于一个m x n矩阵,其中m或n是2的幂,你可以计算出sum\u range(0,m-1)*n,其中sum range只是把第一个和第二个输入之间的每个数字相加。
当m和n都不是2的幂时,事情就变得有趣了。
可以将mxn矩形拆分为一个由两个次幂的子mxn矩形组成的矩形,如下所示:(15x15)
0, 1, 2, 3, 4, 5, 6, 7 | 8, 9, 10, 11 | 12, 13 | 14 |
1, 0, 3, 2, 5, 4, 7, 6 | 9, 8, 11, 10 | 13, 12 | 15 |
2, 3, 0, 1, 6, 7, 4, 5 | 10, 11, 8, 9 | 14, 15 | 12 |
3, 2, 1, 0, 7, 6, 5, 4 | 11, 10, 9, 8 | 15, 14 | 13 |
4, 5, 6, 7, 0, 1, 2, 3 | 12, 13, 14, 15 | 8, 9 | 10 |
5, 4, 7, 6, 1, 0, 3, 2 | 13, 12, 15, 14 | 9, 8 | 11 |
6, 7, 4, 5, 2, 3, 0, 1 | 14, 15, 12, 13 | 10, 11 | 8 |
7, 6, 5, 4, 3, 2, 1, 0 | 15, 14, 13, 12 | 11, 10 | 9 |
----------------------------------------------------
8, 9, 10, 11, 12, 13, 14, 15 | 0, 1, 2, 3 | 4, 5 | 6 |
9, 8, 11, 10, 13, 12, 15, 14 | 1, 0, 3, 2 | 5, 4 | 7 |
10, 11, 8, 9, 14, 15, 12, 13 | 2, 3, 0, 1 | 6, 7 | 4 |
11, 10, 9, 8, 15, 14, 13, 12 | 3, 2, 1, 0 | 7, 6 | 5 |
----------------------------------------------------
12, 13, 14, 15, 8, 9, 10, 11 | 4, 5, 6, 7 | 0, 1 | 2 |
13, 12, 15, 14, 9, 8, 11, 10 | 5, 4, 7, 6 | 1, 0 | 3 |
----------------------------------------------------
14, 15, 12, 13, 10, 11, 8, 9 | 6, 7, 4, 5 | 2, 3 | 0 |
----------------------------------------------------
然后,使用我上面描述的公式,你可以得到对角线上每个平方的和(我的解释没有意义,所以这里是一张图片):嵌入的声誉不够。
我就是这样
我不知道如何得到其他部分的总和,用m和n表示,而不需要暴力的强迫。记住,m和n是随机整数,它们可能非常大
我看到了一些模式,比如魔方是如何对称的,边是0-(m-1)的数字,但是,我没能想出逻辑来把它转换成代码。
如果你能给我指出正确的方向,我将不胜感激。然而,不是寻找代码,因为这是一个代码战争的问题,这是欺骗
参考问题:https://www.codewars.com/kata/59568be9cc15b57637000054/train/java
2条答案
按热度按时间oewdyzsn1#
对于每个位,计算该位的多少个示例对总和的贡献:
假设有r行的数字中设置了该位,而r行的数字中没有该位。c列和c列也是如此。
具有该位集的单元数为rc+rc。
对于每个位,将位值*(rc+rc)加到总计中。
例如,对于4行5列:
位0在列号[1,3]中设置,在列号[0,2,4]中清除,因此c=2,c=3。它在行号[1,3]中设置,在行号[0,2]中清除,所以r=2,r=2。我们把(2^0)(23+22)=10加到总数上。
位1在列号[2,3]中设置,在列号[0,1,4]中清除,因此c=2,c=3。它在行号[2,3]中设置,在行号[0,1]中清除,所以r=2,r=2。我们把(2^1)(23+22)=20加到总数上。
第2位在第[4]列中设置,在第[0,1,2,3]列中清除,因此c=1,c=4。它在行号[]中设置,在行号[0,1,2,3]中清除,所以r=0,r=4。我们把(2^2)(0+14)=16加到总数上。
总计=10+20+16=46。
pengsaosao2#
我们可以将矩阵分为四个子尺度,然后利用
sum_range(start, m-1) * n
一遍又一遍。为了简单起见,我将解释如何使用递归,您可以使用queue轻松地将其转换为非递归解决方案。让我们考虑一个小的更糟的情况,一个7x7矩阵。其中,m=7(列),n=7(行)。总和168。
我们可以将此矩阵分为以下4个矩阵:
这里第一个矩阵的维数等于2的最大可能幂,也就是4。其余的只是父矩阵的剩余3部分。
我们可以用这个公式得到第一个矩阵的和:
rowSum*rows -> (m*(m-1)/2)*n -> (4*3/2)*4 -> 24
接下来我们考虑第二个子矩阵。用同样的策略分成4部分:这里,第一个子矩阵可以用公式计算
(rowSum - startSum)*rows
->((m*(m-1)/2) - (start*(start-1)/2)) * n
->(6*5/2 - 4*3/2)*2
->18
. 在这里,start = 4 xor 0
.通过以上讨论,我们可以创建如下递归函数:
上述代码应产生如下输出:
注:按作者要求,不提供工作代码。