我正在获取1到n个数字,并找到可以被a或b整除但不能被两者整除的数字计数。 我想通过一些逻辑上的更改来减少此块的时间复杂度。
cin >> n >> a >> b >> k;
for(int i = 1; i <= n; i++) {
if(i % a == 0 && i % b==0) {
count++;
} else if(i % b == 0 && i % a != 0) {
count++;
}
}
答案 0 :(得分:4)
计算可被a整除的数字计数,将其加到可被b整除的数字计数上,再减去可被a,b的lcm(最小公倍数)整除的数字计数的两倍。
时间复杂度:O(log(min(a,b)))
由于要计算最低公倍数,因此计算出gcd(最大公除数),可以在O(log(min(a,b)))
中计算
注意:如果包含bits/stdc++.h
,则可以使用内置函数来计算gcd: __ gcd(int,int)
int lcm(int a, int b) {
return (a * b)/__gcd(a,b);
}
cin>>n>>a>>b>>k;
int divisible_by_a = n / a;
int divisible_by_b = n / b;
int divisible_by_both = n / lcm(a,b);
ans = divisible_by_a + divisible_by_b - 2*divisible_by_both;
答案 1 :(得分:0)
在我看来,您的代码无法按照您所描述的那样工作:它被b
整除的每个数字都计数。您应该检查我是a还是b的倍数
if (i % a == 0 && i % b != 0) {...
} else if (i % a != 0 && i % b == 0) {...
}
我还建议您使用另一种方法:找到a
和b
的倍数,直到达到n
并计算该数字。从总和中删除列表中的相同数字(最好在最终总和之前删除)
答案 2 :(得分:0)
在对其进行优化之前,请确保它首先起作用。
现在,您正在检查一个数字是否只能被lambda=0
或两者 b
和a
整除。要使其b
或a
但不能同时使用两者,您需要在第一种情况下将b
切换为i % b==0
:
i % b!=0
您可以做的一件小事就是加快检查速度,并只将结果保存一次,而不是保存两次。然后,您可以将单个XOR用于最终结果。
for(int i = 1; i <= n; i++) {
if(i % a == 0 && i % b!=0) {
count++;
} else if(i % b == 0 && i % a != 0) {
count++;
}
}
答案 3 :(得分:0)
让我们从这里开始:
temp = a;
while(temp < n) {
if(temp%b != 0) {
count++;
}
temp += a;
}
temp = b;
while(temp < n) {
if(temp%a != 0) {
count++;
}
temp += b;
}
接下来,考虑一些作弊。如果a%b == 0
,那么任何a
可整除的数字也将被b
除整;与b%a == 0
类似。在两种情况下,计数都必须为零。
如果a == 0
不能被a
整除;与b == 0
类似;并且如果a
和b
均为零,则计数必须为零。
最后;别忘了({C}中x%0
的行为是不确定的,您需要注意这一点。
结合以上所有内容,您将获得类似的信息:
if( (a == 0) && (b == 0) ) {
return 0;
}
if( (a != 0) && (b != 0) ) {
if( (a%b == 0) || (b%a == 0) ) {
return 0;
}
}
count = 0;
if(a != 0) {
temp = a;
while(temp < n) {
if(temp%b != 0) {
count++;
}
temp += a;
}
}
if(b != 0) {
temp = b;
while(temp < n) {
if(temp%a != 0) {
count++;
}
temp += b;
}
}
return count;
下一轮作弊:
n <= 1
,则计数必须为零。a == 1
或a == -1
,则所有数字都可以被a
整除。b == 1
或b == -1
,则所有数字都可以被b
整除。要处理这些问题,我将转到“嵌套开关”以最小化分支的数量,例如:
switch(a) {
case 0:
switch(b) {
case 0:
...
break;
case -1:
case 1:
...
break;
default:
...
break;
}
break;
case -1:
case 1:
switch(b) {
case 0:
...
break;
case -1:
case 1:
...
break;
default:
...
break;
}
break;
default:
switch(b) {
case 0:
...
break;
case -1:
case 1:
...
break;
default:
...
break;
}
break;
}