今日刷题——数学知识篇(一)
下面的题目多数已被
vritual judge平台收录
质数
试除法判定小质数
#include <iostream>
using namespace std;
bool isPrime(int n) {
if (n < 2) return false;
for(int i = 2;i <= n / i;i++) { //以根号n为界,如果n存在一个小于根号n的约数a
if (n % i == 0) //那么相应地也存在一个大于根号n的约数b
return false; //只要n不会被i整除,那么也不会被n/i整除
} //要判定质数只要验证[2,根号n]范围内没有n的
//约数,即 i <= 根号n == i * i <= n
return true; // == i <= n/i,调用sqrt()函数较慢
} //而i*i有超出int类型表示范围的风险,故
//采用i <= n / i的形式
int main() {
int n;
cin >> n;
cout << (isPrime(n) ? "YES" : "NO");
return 0;
}
相似题目:
计蒜客T1319-质数判定一
计蒜客T1307-质数判定二
计蒜客T1579-质数判定三
51nod 1106-质数检测
Miller-Rabin测试判定大质数
未完待续
分解质因数
#include <iostream>
using namespace std;
int main() {
int n, max = 1;
cin >> n;
for (int i = 2; i <= n / i; i++) { //想象做数学题的时候分解一个数就是从2开始
if (n % i == 0) { //不断地对数进行分解,直到无法整除后才换3
while (n % i == 0) //试试,以此类推,直到分解出的数是个素数
n /= i; //为止。如果有比根号n还大的质因数那也只有
if (i == n / i) //一个,假如有两个那这两个因数相乘不就大于
max = i; //n了吗,显然矛盾。因此i只要试探到了根号n
} //就行了,如果剩下的数比1还大,那它就是
} //那个大于根号n的质因数
if (n > 1)
max = n;
cout << max;
return 0;
}
相似题目
51nod 2122-分解质因数
LibreOJ 6466-分解质因数
leetcode 952-按公因数计算最大组件大小
筛质数
埃氏筛法
简单思路:2是质数,但2的倍数不是质数,3也是质数,但质数的倍数都不是质数。
从2开始对[2,n]范围内的质数的倍数(即合数)打上标记。
所有合数都被标记了那质数也就被筛出来了。
#include <cstdio>
#include <bitset>
using namespace std;
#define read(x) scanf("%d",&x);
const int N = 1e8 + 10;
int prime[N / 2],cnt;
bitset<N> vis;
void ehrlich(int n) {
for(int i = 2;i <= n / i;i++) {
if (!vis[i]) {
for(long long j = 1ll * i * i;j <= n;j += i)
vis[j] = true;
}
}
prime[++cnt] = 2;
for(int i = 3;i <= n;i+=2)
if (!vis[i])
prime[++cnt] = i;
}
int main() {
int n,q;
scanf("%d %d",&n,&q);
ehrlich(n);
while(q--) {
int k;
read(k);
printf("%d\n",prime[k]);
}
return 0;
}
欧拉筛法
简单思路:从2到n开始的数如果没标记了就是合数,没被标记就是质数。起初默认都是合数。从2开始将素数放入素数集合中。
欧拉筛法希望每个合数只会由它的最小质因子来标记。因此从小到大遍历每个进入集合的素数并将 i 倍的素数标记为合数除非
当前素数已与 i 一样大或当前素数与 i 的最小质因子一样大。
#include <cstdio>
#include <bitset>
using namespace std;
const int N = 1e8 + 10;
int prime[N / 2],cnt;
bitset<N> vis;
void linear(int n) {
for(int i = 2;i <= n;i++) {
if (!vis[i]) prime[cnt++] = i;
for(int j = 0;1ll * i * prime[j] <= n;j++) {
vis[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
}
int main() {
int n,q;
scanf("%d %d",&n,&q);
linear(n);
while(q--) {
int k;
scanf("%d",&k);
printf("%d\n",prime[k - 1]);
}
return 0;
}