不可整除的数字
Number that are not divisible
本文关键字:数字 更新时间:2023-10-16
你会得到一个正整数N。你的任务是找到正整数 K ≤ N 的数量,使得 K 不能被集合 {2,3,4,5,6,7,8,9,10} 中的任何数字整除。
我在想所有的素数,但它没有给出正确的答案。
令人惊讶的是,答案非常简单。
#include <iostream>
using namespace std;
int main() {
int t;
cin>>t;
while(t--) {
long long n;
cin>>n;
long long ans = (n/2+n/3+n/5+n/7)-(n/6+n/10+n/14+n/15+n/21+n/35)+(n/30+n/42+n/70+n/105)-(n/210);
cout<<n - ans<<endl;
}
return 0;
}
但我不明白这个算法。谁能给我解释一下这个算法。
集合中的素数是 2、3、5 和 7。使用这些,我们计算:
how many numbers up to N are divisible by 2, 3, 5 and 7
但后来我们高估了可被两者整除的数字:
2,3 = 6
2,5 = 10
2,7 = 14
etc.
但随后我们过度减去所有可被所有三个数字整除的数字:
2,3,5 = 30
2,3,7 = 42
etc.
等。。。
这种组合原理称为包含-排除。
这个过程之后剩下的任何东西都不能被这些素数整除。(请注意,如果一个数字不能被 2 整除,则它不能被 4、6、8 和 10 整除;3 和 9 也是如此。
首先,计算集合中不能被素数整除的数字。
-
n/2
个数字不能被 2 整除。 -
n/3
的数字不能被 3 整除。 - 等。
但是,有些数字被计算了两次。不能被 6 整除的数字既不能被 2 整除,也不能被 3 整除,所以我们从总数中减去它们。
像 30 这样的数字在第一阶段被计算了三次(作为 2、3 和 5 的倍数(,但在第二阶段被计算了三次(作为 6、10 和 15 的倍数(。因此,我们必须再次将它们相加,净贡献为 1。
因此,最终答案中的每个括号表达式表示计算集合中不能被数字整除的数字,或者补偿先前的高计数或少计数。
存在非递归解决方案。
int N = ....;
int const primes[4] = {2,3,5,7};
int result = 0;
for(int i = 0; i < 16; ++i)// 16 = 2^4
{
int p = 1, s = 1; // s = (-1)^bits(i).
for(int j = 0; j < 4; ++j)
if ( ( i >> j ) & 1 )
p *= primes[j], s *= -1;
result += (N / p) * s;
}
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 检查输入是否不是整数或数字
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何用数字处理log(0)
- 最高有效数字侧的第N位
- 如何获取一个数字的前3位
- 查找最接近的大于当前数字的数字的索引
- 找到两对数字,使它们的乘积的绝对差最小化
- 我想做一个彼此不同但重复出现的数字
- 将数字转换为字母(例如:123 转换为一二三)
- C++如何计算用户输入的数字中的偶数位数
- 如何在C++中确定文本文件中的元素是字符还是数字
- 打印数字图案
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 如何检查一个c++字符串中有多少相同的字符/数字
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 将数字打印成文字
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 在将数字随机生成为数组期间从内存输出随机数的数组