给定一个正整数个对象,比如小盒子,我想把它们整齐地放在一个漂亮的2d块中的桌子上,这个块可能会也可能不会形成一个矩形,但不是任何旧的矩形,一个尽可能接近正方形。 为此,我需要两个整数,它们将整数个对象分开,尽可能彼此接近。
例如;
说我有12个对象。我可以将它们列为
(12 x 1)或(1 x 12)或(6 x 2)或(2 x 6)或(3 x 4)或(4 x 3)
我希望它们为(4 x 3),甚至是(3 x 4)但是假设最大值是第一个,因为这是最大的一对除以最接近的数字。
给定一些正整数x,什么算法会返回(y,z)where;
((y * z)= x)AND(y> z)AND(abs(y - z)是最小值)
如果没有解决方案,我可以通过增加整数来搜索解决方案,从我实际拥有的对象数量开始,找到附近的解决方案,然后适合我对象进入该解决方案,留下空白。
但是...... 现在让我们加快步伐!
如果我现在把它扩展到3d而不是平面上,我想做一个漂亮的整齐块,假设立方体,3d空间中的对象具有CLOSEST三个数字,它们除以整数尽可能彼此靠近的物体,以便从这些物体中形成最紧凑,紧密堆积的三维结构? 例如;
说我有12个对象。我可以将它们安排为
(12 x 1 x 1)或(1 x 12 x 1)或(1 x 1 x 12)或(2 x 2 x 3)或(2 x 3 x 2)或(3 x 2 x 2) ...
我接受它们作为一个紧凑的(3 x 2 x 2)物体块。
不是数学家,首先,这是什么类型的因素问题,其次,是否存在可以对任何正整数执行此操作的算法,并建议何时无法解决。< / p>
我知道它首先考虑整数,然后......
奖励积分......还有办法做4维解决方案吗? N维?
我试图编写C ++算法,但这是我遇到的整数数学问题。
感谢-你。
答案 0 :(得分:1)
您希望将 n 整数分解为 k 因子,最大限度地减少所有 k i 之间的总欧几里德距离>。如果0 <0,则始终存在解决方案。 k 且0&lt; 名词的。例如,考虑 n =任何素数:解决方案是{ n } + {1重复 k - 1次}。
递归伪代码方法:
list<int> reduce(int n, int k, list<int> factors)
// validity checks for 0 < k, 0 < n omitted
// if there's only one factor left, we know what it is
if(k == 1)
factors.add(n)
return factors
// we know all the remaining factors because n can't be reduced further
if(n is prime || n == 1)
factors.add(n)
return reduce(1, k - 1, factors)
// take the k-th root of n, rounded up
int r = ceiling(root(n, k))
// if there's an exact root here, we're done; remaining factor distance = 0
if(n % r == 0)
do k times
factors.add(r)
return factors
// otherwise find the next largest remaining factor
while(n % r != 0)
r -= 1
factors.add(r)
return reduce(n / r, k - 1, factors)
此代码旨在明确而非优化。
从概念上讲,您试图通过从直角点扩展所有 k 因子来最小化形成的对角线测量值。如果 k = 2,则将 k 0 与成直角放置后形成的直角三角形的斜边最小化>ķ<子> 1 子> 的。对于 k = 3,它通过使所有三个因子正交(即形成三维笛卡尔图的X-Y-Z轴)来最小化三角形的面积。对于 k = 4,它使四面体固体的体积最小化;为了迭代地构建这个形状,上面的算法使用 k -th root来绑定要添加的新维度的大小。
如果您希望对结果进行排序,那么只需对返回的列表进行排序即可。据推测 n &gt;&gt; k ,因此与分解成本相比,该类别的 k log k 成本是微不足道的。或者我想如果你是懒惰的话,可以使用自我排序数据结构作为返回类型。
一些例子有效:
n = 12,k = 3
n = 32,k = 3
n = 25,k = 4
更多结果: