面试街道挑战中的错误答案

时间:2012-10-30 06:24:35

标签: algorithm numbers lcm greatest-common-divisor

首先是一个小小的澄清。我在这个问题上确实得到了AC,但是我的更好的方法(在数学上等同,我假设我的AC解决方案)正在获得WA判决 在面试街有一个问题,如下:

  

有一个友好号码和N个不友好号码。我们想知道有多少数字与友方数字完全分开,但不会划分任何不友好的数字。

     

输入格式:

     

第一行输入包含两个以空格分隔的数字N和K. N是不友好号码的数量,K是友好号码。第二行输入包含N个空格分隔的不友好数字。

     

输出格式:

     

将答案输出一行。

     

示例输入:

     

8 16
  2 5 7 4 3 8 3 18

     

示例输出:

     

1

     

说明:

     

给定友方号码16的除数是{1,2,4,8,16}且不友好   数字是{2,5,7,4,3,8,3,18}。现在1除了所有不友好的数字,2除以2,   4除以4,8除8,但16除以它们中的任何一个。因此,只有一个号码可以划分友方号码,但不会划分任何不友好的号码。所以答案是1。

我的Algo(获得AC)如下:

  1. 让可能不友好的数字输入[i],其中0 <= i

  2. 对于每个输入[i]找到gcd(input [i],k)。

  3. 在集合中存储范围(0,n)中所有i的gcd(input [i],k)的所有因子。让我们调用此set PossibleFactors。

  4. 对于k的每个因子,检查它是否除以PossibleFactor中的任何元素。如果没有则增加回答次数

  5. 我修改了算法,假设如下:

    不是将gcd的所有因子(input [i],k)存储在一个集合中,找出范围(0,n)中所有i的gcd(input [i],k)的lcm。 这可以通过以下LOC轻松完成

    lcm = (lcm/gcd(gcd(input[i],k),lcm))*(gcd(input[i],k))
    

    现在针对k的所有因素检查它们是否除以lcm。如果没有则增加计数。

    然而,这个假设给了我WA。是因为我的逻辑存在任何缺陷吗?如果是,请指出(如果可能的话,有数学证明)这两种方法有何不同?

    这是我的代码,第二种方法是参考(和可能的错误)

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    typedef long long LL;
    LL gcd(LL a,LL b) {
        LL c;
        while(b) {
            c=a%b;
            a=b;
            b=c;
        }
        return a;
    }
    int main()
    {
        long long int n,k,i,x,j,ans=0,a,num,g;
        scanf("%lld%lld",&n,&k);
        num=1;
        for(i=0;i<n;i++) {
            scanf("%lld",&a);
            g=gcd(a,k);
            num=(num/gcd(num,g))*g;
        }
        x=sqrt(k);ans=0;
        for(i=1;i<=x;i++) {
            if(!(k%i)) {
                if((num%i)) ans++;
                if((k/i != i) && (num%(k/i))) ans++;
            }
        }
        printf("%lld\n",ans);
        return 0;
    }
    

1 个答案:

答案 0 :(得分:1)

你说“找出范围(0,n)中所有i的gcd(输入[i],k)的lcm ...现在对于k的所有因子,检查它们是否除了lcm。如果没有则增加计数。“

该方法存在缺陷。考虑k = 20,U = [12,25,30]的情况。然后GCDs = [4,5,10]并且LCM = 20.因此k的所有因子除以LCM,导致引用标准的零计数。但是k本身并没有划分任何U,所以count应该是1而不是0。

相关问题