题目总结
0x01:试除法判定质数
【题目】
给定n个正整数 ai ,判定每个数是否是质数。
【输入格式】
第一行包含整数n。
接下来n行,每行包含一个正整数 ai 。
【输出格式】
共n行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出“Yes”,否则输出“No”。
【数据范围】
1≤n≤100 ,
1≤ai≤231−1
【输入样例】
2
2
6
【输出样例】
Yes
No
0x02:分解质因数
【题目】
给定n个正整数 ai ,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。
【输入格式】
第一行包含整数n。
接下来n行,每行包含一个正整数 ai 。
【输出格式】
对于每个正整数 ai ,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。
每个正整数的质因数全部输出完毕后,输出一个空行。
【数据范围】
1≤n≤100 ,
1≤ai≤2∗109
【输入样例】
2
6
8
【输出样例】
2 1
3 1
2 3
【CODE】
#include<iostream>
#include<vector>
using namespace std;
typedef pair<int, int>PII;
void work(int num){
vector<PII> a;
for(int i = 2; i <= num / i; ++i){ // sqrt优化
int s = 0;
while(num % i == 0){
s ++;
num /= i;
}
if(s) a.push_back({i, s});
}
if(num > 1) a.push_back({num, 1}); // 最后判断num的值
for(auto x : a){
cout << x.first << " " << x.second << endl;
}
}
int main(){
int T;
cin >> T;
while(T --){
int a;
cin >> a;
work(a);
cout << endl;
}
return 0;
}
给定一个正整数n,请你求出1~n中质数的个数。
输入格式
共一行,包含整数n。
输出格式
共一行,包含一个整数,表示1~n中质数的个数。
数据范围
1≤n≤106
输入样例:
8
输出样例:
4
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n, cnt;
int st[N], p[N];
// 朴素筛法-O(nlogn)
void get_primes(int num){
for(int i = 2; i <= num; ++i){
if(!st[i]) p[cnt ++] = i;
for(int j = i + i; j <= num; j += i){ // 将每个数的倍数全部去除
st[j] = true;
}
}
}
// 埃式筛法-O(nlognlogn)
void get_primes(int num){
for(int i = 2; i <= num; ++i){
if(!st[i]){
p[cnt ++] = i;
// 把质数的倍数删去
for(int j = i; j <= num; j += i){
st[j] = true;
}
}
}
}
// 线性筛法-O(n) --- 不懂
void get_primes(int num){
for(int i = 2; i <= num; ++i){
if(!st[i]) p[cnt ++] = i;
for(int j = 0; p[j] <= num / i; ++j){
st[p[j] * i] = true;
if(i % p[j] == 0) break;
}
}
}
int main(){
cin >> n;
get_primes(n);
cout << cnt << endl;
return 0;
}
给定两个整数 L 和 U ,你需要在闭区间 [L,U] 内找到距离最接近的两个相邻质数 C1 和 C2 (即 C2−C1 是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。
同时,你还需要找到距离最远的两个相邻质数 D1 和 D2 (即 D1−D2 是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。
输入格式
每行输入两个整数 L 和 U ,其中 L 和 U 的差值不会超过 106 。
输出格式
对于每个 L 和 U ,输出一个结果,结果占一行。
结果包括距离最近的相邻质数对和距离最远的相邻质数对。(具体格式参照样例)
如果 L 和 U 之间不存在质数对,则输出 There are no adjacent primes.。
数据范围
1≤L<U≤231−1
输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent prim
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1000010;
int primes[N], cnt;
bool st[N];
void get_primes(int n)
{
memset(st, false, sizeof st);
cnt = 0;
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] * i <= n; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
int main()
{
long long l, r;
while (cin >> l >> r)
{
get_primes(50000); // 因为2的31次方内的合数都可以被最小的质数给化解,所以先搜 2 ~ 2的31次方开方个数
memset(st, false, sizeof st);
for (int i = 0; i < cnt; i ++ ) // 去除【l ,r】之间的合数
{
int p = primes[i];
// 把[l, r]中所有p的倍数筛掉
// 2ll * p, 不可以把自己筛掉,所以至少要从2p开始
// (l + p - 1) / p = l / p 上取整
for (long long j = max((l + p - 1) / p * p, 2ll * p); j <= r; j += p)
st[j - l] = true;
}
cnt = 0;
for (int i = 0; i <= r - l; i ++ ) // 计算除所有质数
if (!st[i] && i + l > 1) // 1(不取) 的情况要考虑,
primes[cnt ++ ] = i + l;
if (cnt < 2) puts("There are no adjacent primes.");
else
{
int minp = 0, maxp = 0;
for (int i = 0; i + 1 < cnt; i ++ )
{
int d = primes[i + 1] - primes[i];
if (d < primes[minp + 1] - primes[minp]) minp = i;
if (d > primes[maxp + 1] - primes[maxp]) maxp = i;
}
printf("%d,%d are closest, %d,%d are most distant.\n", primes[minp], primes[minp + 1], primes[maxp], primes[maxp + 1]);
}
}
return 0;
}
给定整数 N ,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pi 和 ci 即可。
输入格式
一个整数 N 。
输出格式
N! 分解质因数后的结果,共若干行,每行一对 pi,ci ,表示含有 pcii 项。按照 pi 从小到大的顺序输出。
数据范围
1≤N≤106
输入样例:
5
输出样例:
2 3
3 1
5 1
样例解释
5!=120=23∗3∗5
【解题思路】
找出 1 ~ n 之间所有的质数
再 n! 中 质数 p 对应的次方为 :n / p + n / p2 + …
公式理解:
【CODE】
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int primes[N], cnt;
bool st[N];
void get_primes(int n){
for(int i = 2; i <= n; ++i){
if(!st[i]) primes[cnt ++] = i;
for(int j = 0; primes[j] * i <= n; ++j){
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
int main(){
int n;
cin >> n;
get_primes(n);
// for(int i = 0 ; i < cnt; ++i){
// cout << primes[i] << endl;
// }
for(int i = 0; i < cnt; ++i){
int p = primes[i];
int s = 0, t = n;
while(t){
s += t / p;
t /= p;
}
cout << p << " " << s << endl;
}
return 0;
}