我只是在想一个似乎并不难的问题,但是当我们考虑以最佳方式进行时,它就变成了一个很好的问题。问题是 - 我们得到了一个数字列表(数组)和一个数字 N。我们必须找到 N 的所有除数,它们不会除掉任何属于该列表的数字。我已经用蛮力和一点有效的方法(但不是最好的方法)解决了它。所以,我正在寻找一种可能是解决这类问题的最佳方法。一切都是整数(没有浮点数)。每一个想法都值得赞赏。
我的方法是首先找到数字 N 的所有除数(没有任何开销)。然后,我以相反的顺序(单独)对列表和除数进行排序。现在,对于每个除数 D,我检查它是否除以列表中的任何数字(从最高元素开始到 >= 除数 D 的元素)。如果它除法,那么 D 的所有除数也必须除法。然后我从除数列表中删除这些元素,这些元素也是 D 的除数(可以认为是删除交集)。因此,最终左除数数组是所需的数组(根据我的方法)。如果有人可以指出我的方法中的任何错误或效率低下,我们将不胜感激。列表中可以存在的最大值为 10^18。
到目前为止我在 PHP 中的尝试:
while($div=each($divisors))
{
$i=0;
$divisor=$div['key'];
//echo "divisor is $divisor\n";
while((int)$unfriendly[$i]>=$divisor)
{//echo "aya\n";
if(!((int)bcmod($unfriendly[$i],$divisor)))
{//echo "ayeea\n";
$divisors_of_divisor=divisors_of_a_number($divisor);
//print_r($divisors_of_divisor);
//print_r($divisors);
foreach($divisors_of_divisor as $d)
unset($divisors[$d]);
//print_r($divisors);
break;
}
++$i;
}
}
echo sizeof($divisors);
function divisors_of_a_number($n)//returns all the divisors of a number in an unsorted array
{
$i=1;
$s=sqrt($n);
while($i<=$s)
{
if(!($n%$i))
{
$a[]=$i;
if($i!=$s)
$a[]=$n/$i;
}
++$i;
}
return $a;
}
function divisors_of_a_number_as_keys_of_array($n)//returns all the divisors of a number in an unsorted array as keys
{
$i=1;
$s=sqrt($n);
while($i<=$s)
{
if(!($n%$i))
{
$a[$i]=1;
//if($i!=$s)
$a[$n/$i]=1;
}
++$i;
}
return $a;
}