对于UVa Online Judge上的问题10139 - Factovisors,我们会给出2个数字n
和m
,我们需要检查m
是否划分n!
。
我使用算法:
生成素数直到常数
选择m
并获取其素数因子
对于m
个因素中的每个素数,计算getpower
的{{1}}函数并进行比较
我测试了不同的案例,它给了我错误的答案,任何建议?
这是我的代码:
n
答案 0 :(得分:2)
也许你的黄金时代有问题,但肯定你的get_powers
实施容易被int
溢出。
int get_powers (int n, int p) {
int result = 0, power = p;
while (power <= n) {
result += n / power;
power =power* p;
}
return result;
}
如果int
通常是32位宽类型,对于大于46341的素数,计算power = power * p;
在第一次完成时溢出。这可能导致错误的结果,例如
get_powers(10000000, 131071)
如果溢出行为是模数2 32 ,则返回52,但正确的结果是76.现在,因为m
小于2 31 ,这个特别的人不会受到伤害,因为m
不能被131071²整除。但在环绕行为下,
get_powers(1000000, 699733) = -2192
是否定的,因此对于n = 1000000
和m = 2*699733
,您会错误地断定n!
不能被m
整除。
为避免可能的溢出,只能除以p
,
int get_powers(int n, int p) {
int result = 0;
n /= p;
do {
result += n;
n /= p;
}while(n > 0);
return result;
}
来自评论:
我编辑添加我的函数以获得素数直到常数“maxn0” - userG 2小时前
您为maxn0选择了什么价值? - Daniel Fischer 2小时前
maxn0 = 10000
这个值太小了。
当素数达到10000时,您只能保证正确分解不超过10 8 的数字(好吧,因为下一个素数是10007,数字小于10007² = 100140049
),但是限制为2 31 ,这个数字要大得多。
每当给出一个数字m
时,两个(不一定是不同的)素数因子大于10000,你就不会正确地将其分解,这通常会导致错误的答案。
您需要所有素数≤√(2 31 -1),即所有素数< 46340
,以获得所有可接受m
的正确因子分解。
答案 1 :(得分:0)
9分7!但是你的算法会回答错误,因为get_powers(7, 3) == 0
和3是因子9。
这不是你的实现错误,而是你的算法。