首先是一个小小的澄清。我在这个问题上确实得到了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)如下:
让可能不友好的数字输入[i],其中0 <= i
对于每个输入[i]找到gcd(input [i],k)。
在集合中存储范围(0,n)中所有i的gcd(input [i],k)的所有因子。让我们调用此set PossibleFactors。
对于k的每个因子,检查它是否除以PossibleFactor中的任何元素。如果没有则增加回答次数
我修改了算法,假设如下:
不是将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;
}
答案 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。