1.试除法判断某个数是否为质数
#include <iostream> using namespace std; const int N = 50005; bool is_prime1(int n) { // 暴力写法:O(n) if (n < 2) return false; for (int i = 2; i < n; i++) { if (n % i == 0) return false; } return true; } // 优化,每次只枚举较小的一个约数 bool is_prime2(int n) { // O(根号n) if (n < 2) return false; for (int i = 2; i <= n / i; i++) { if (n % i == 0) return false; } return true; } int main() { return 0; }
2. 分解质因数
给定 n 个正整数 ai,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个正整数 ai。
输出格式
对于每个正整数 ai,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。
每个正整数的质因数全部输出完毕后,输出一个空行。
数据范围
1≤n≤100
2≤ai≤2×10^9
输入样例:
2 6 8
输出样例:
2 1 3 1 2 3
#include <iostream> using namespace std; const int N = 50005; void divide1(int n) { for (int i = 2; i <= n; i++) // 底数一定为质数(因为从小到大枚举) { // 暴力 O(n) if (n % i == 0) { int s = 0; while (n % i == 0) { n /= i; s++; } cout << i << " " << s << endl; // 底数,指数 } } cout << endl; } // 优化:n中最多只包含一个大于sqrt(n)的质因子(反证:如果有两个,则乘起来>n) void divide2(int n) { for (int i = 2; i <= n / i; i++) { // O(logn)~O(根号n) if (n % i == 0) { int s = 0; while (n % i == 0) { n /= i; s++; } cout << i << " " << s << endl; // 底数,指数 } } if (n > 1) // 最后剩下的数要么为1,要么为大于sqrt(n)的质因子 cout << n << " " << 1 << endl; // 特殊处理即可 cout << endl; } int main() { int n; cin >> n; while (n--) { int x; cin >> x; divide2(x); } return 0; }
3. 筛质数
给定一个正整数 n,请你求出 1∼n中质数的个数。
输入格式
共一行,包含整数 n。
输出格式
共一行,包含一个整数,表示 1∼n 中质数的个数。
数据范围
1≤n≤10^6
输入样例:
8
输出样例:
4
#include <iostream> using namespace std; const int N = 1000010; int primes[N], cnt; bool st[N]; void get_primes1(int n) { // O(lnn) for (int i = 2; i <= n; i++) { if (st[i] == 0) { primes[cnt++] = i; // 存质数 } for (int j = i + i; j <= n; j += i) { st[j] = true; // 将i的倍数删去 } } } // 优化:不必枚举2~p-1,只需枚举里面的质数 void get_primes2(int n) // 埃氏筛:原理:在朴素筛法的过程中只用质数项去筛. { // O(nloglogn) for (int i = 2; i <= n; i++) { if (st[i] == 0) { primes[cnt++] = i; for (int j = i + i; j <= n; j += i) { st[j] = true; // 将i的倍数删去 } } } } // 线性筛法 void get_primes3(int n) { // 原理:1~n之内的任何一个合数一定会被筛掉,而且筛的时候只用最小质因子来筛, // 然后每一个数都只有一个最小质因子,因此每个数都只会被筛一次,因此线性筛法是线性的. for (int i = 2; i <= n; i++) { if (st[i] == 0) { primes[cnt++] = i; } for (int j = 0; primes[j] <= n / i; j += i) { st[primes[j] * i] = true; if (i % primes[j] == 0) break; } } } int main() { int n; cin >> n; get_primes2(n); cout << cnt << endl; return 0; }