我想编写一个函数,用于查找数字N的联合素数,这些数字小于数字M,使得M
为此,我参考了这个链接modifying Euler Totient Function
我写了一个下面的递归代码。
int f(int *factors, int start, int nf, int m) //nf=no. of factors, start=0, m=M
{
if(start == nf-1)
return (m / factors[start]);
return (m / factors[start]) + f(factors, (start + 1), nf, m) - ((f(factors, (start + 1), nf, m)) / factors[start]);
}
但是,我的回答是错误的。
我想解决这个问题http://www.spoj.pl/problems/HNUMBERS/
我的代码为给定的测试用例提供了正确的答案,但是对于其他一些测试用例却失败了(因为他们给我错误的答案)。
答案 0 :(得分:1)
你的函数f
(或许应该选择一个更具描述性的名称)似乎意味着返回不超过m
的数字的数量,这些数字可以被数组中的任何素数整除{{ 1}},从索引factors
开始。
start
显然,只有一个素数int f(int *factors, int start, int nf, int m) //nf=no. of factors, start=0, m=M
{
if(start == nf-1)
return (m / factors[start]);
return (m / factors[start]) + f(factors, (start + 1), nf, m)
- ((f(factors, (start + 1), nf, m)) / factors[start]);
}
,计数为p
。到现在为止还挺好。现在,另一部分的想法是,可以被m / p
或后面的素数之一整除的不超过m
的数字的计数是
p
到目前为止是正确的。但是你的实现假设
count_multiples_of_p + count_multiples_of_other - count_multiples_of_p_and_other
这只是渐近正确的。例如,考虑三个素数count_multiples_of_p_and_other = count_multiples_of_other / p
和[2, 3, 5]
。
您的函数返回
m = 20
但如果算上,有六个数字F([2,3,5], 20) = 20/2 + F([3,5], 20) - F([3,5], 20)/2
-- F([3,5], 20) = 20/3 + 20/5 - (20/5)/3 = 6 + 4 - 1 = 9
= 10 + 9 - (9/2) = 10 + 9 - 4 = 15
不能被三个素数中的任何一个<= 20
整除,所以只有14个是三者中的任何一个的倍数。
考虑1, 7, 11, 13, 17, 19
和任何后续素数的倍数的正确方法是计算不超过p
的任何后续素数的倍数,因为如果m/p
是k
的倍数以及后续素数中的至少一个,则p
是后续素数之一的倍数,不超过k/p
。
所以修复你的函数只需要移动一个括号(好吧,两个,因为你有这么多),
m/p
(你有几对多余的括号,你可以考虑删除其中的一些)。