为什么错误回答Uva:Factovisors

时间:2013-05-10 09:05:31

标签: c++ algorithm

对于UVa Online Judge上的问题10139 - Factovisors,我们会给出2个数字nm,我们需要检查m是否划分n!

我使用算法:

  1. 生成素数直到常数

  2. 选择m并获取其素数因子

  3. 对于m个因素中的每个素数,计算getpower的{​​{1}}函数并进行比较

  4. 我测试了不同的案例,它给了我错误的答案,任何建议?

    这是我的代码:

    n

2 个答案:

答案 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 = 1000000m = 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。

这不是你的实现错误,而是你的算法。