质数的判定——试除法
#include <iostream>
#include <algorithm>
using namespace std;
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i <= n / i; i ++ )// i<=sqrt(n);i*i<=n不推荐,速度比较慢
{
if (n % i == 0)
return false;
}
return true;
}
int main()
{
int n, m;
scanf("%d",&m);
while(m -- )
{
scanf("%d", &n);
if (is_prime(n)) puts("Yes");
else puts("No");
}
return 0;
}
分解质因数——试除法
#include <iostream>
#include <algorithm>
using namespace std;
void divide(int n)
{
for (int i = 2; i <= n / i; i ++ )// n中最多只包含一个大于sqrt(n)的质因子
{
if (n % i == 0)
{
int s = 0;
while (n % i == 0)
{
n /= i;
s ++ ;
}
printf("%d %d\n", i, s);
}
}
if (n > 1) printf("%d %d\n", n, 1);
puts("");// 输出字符串并换行
}
int main()
{
int n, m;
scanf("%d", &m);
while (m -- )
{
scanf("%d", &n);
divide(n);
}
return 0;
}
筛质数
(1)朴素筛法:
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;// 此时i是质数
for (int j = i + i; j <= n; j += i ) st[j] = true;// 删除i的倍数
}
}
(2)埃氏筛法:
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i])
{
primes[cnt ++ ] = i;
for (int j = i + i; j <= n; j += i ) st[j] = true;
}
}
}
(3)线性筛法:
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;// 保证prime[j]一定是prime[j] * i的最小质因数,筛掉primes[j] * i
if (i % primes[j] == 0) break;// primes[j]是i的最小质因数
}
}
}
Accepted:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int cnt, primes[N];
bool st[N];
void get_primes(int n)
{
//...
}
int main()
{
int n;
scanf("%d", &n);
get_primes(n);
printf("%d", cnt);
return 0;
}
试除法求约数
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> get_divisors(int n)
{
vector<int> res;
for (int i = 1; i <= n / i; i ++ )
{
if (n % i == 0)// n%i等于0说明i是n的约数
{
res.push_back(i);
if (n / i != i ) res.push_back(n / i);// 约数都是成对出现,若是x % i != i,我们再将x % i也储存到结果数组中
}
}
sort(res.begin(), res.end());// 排序
return res;
}
int main()
{
int n;
scanf("%d", &n);
while (n -- )
{
int x;
scanf("%d", &x);
auto res = get_divisors(x);
for (auto item : res) printf("%d ", item);
puts("");
}
return 0;
}
约数个数
#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int main()
{
int n;
cin >> n;
unordered_map<int,int> primes;
while(n -- )
{
int x;
cin >> x;
for (int i = 2; i <= x / i; i ++ )
{
while (x % i == 0)
{
x /= i;
primes[i] ++ ;
}
}
if (x > 1) primes[x] ++ ;// 质因数大于sqrt(n)的情况
}
LL res = 1;
for (auto prime : primes) res = res * (prime.second + 1) % mod;
cout << res << endl;
return 0;
}
约数之和
#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int main()
{
int n;
cin >> n;
unordered_map<int,int> primes;
while(n -- )
{
int x;
cin >> x;
for (int i = 2; i <= x / i; i ++ )
{
while (x % i == 0)
{
x /= i;
primes[i] ++ ;
}
}
if (x > 1) primes[x] ++ ;
}
LL res = 1;
for (auto prime : primes)// 核心代码
{
int p = prime.first, a = prime.second;
LL t = 1;
while (a -- ) t = (t * p + 1) % mod;
res = res * t % mod;
}
cout << res << endl;
return 0;
}
最大公约数(欧几里得算法,辗转相除法)
#include<iostream>
using namespace std;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
int n;
cin >> n;
while (n -- )
{
int a, b;
cin >> a >> b;
cout << gcd(a, b) << endl;
}
return 0;
}