1。求最大公约数?
2。求最小公倍数?
3。给定一个正整数N,求 [2,N]中的所有素数
4。质因数分解
这是经典而常见的问题,利用算术基本定理很容易证明!
拓展:求N个数的最小公倍数?
#include
#include
#include
#include
using namespace std;
//最大公约数
int gcd(int a, int b) {
if(b == 0) return a;
else return gcd(b, a%b);
}
//最小公倍数
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
//求一个数所有的约数
void produceDiv(int k) {
//O(n)的时间复杂度会超时
/*
for(int i = 2; i < k; i++) {
if(k%i == 0) {
myHash[k].push_back(i);
}
}
*/
vector<int> V;
int mid = (int)sqrt(k)+1;
for(int i = 2; i < mid; i++) {
if(k%i == 0) {
V.push_back(i);
V.push_back(k/i);
}
}
for(int i = 0; i < (int)V.size(); i++) {
cout << V[i] << " ";
}
cout << endl;
}
int main()
{
int a, b;
while(scanf("%d%d", &a, &b) != EOF) {
int res1 = gcd(a, b);
int res2 = lcm(a, b);
cout << res1 << " " << res2 << endl;
}
int k;
while(cin >> k) {
produceDiv(k);
}
return 0;
}
3。给定一个正整数N,求 [2,N]中的所有素数。
方法一:
#include
#include
#include
using namespace std;
const int maxn = 1000000;
bool valid[maxn];
//保存素数index=1开始
int ans[maxn];
void getPrime(int n, int &tot) {
memset(valid, true, sizeof(valid));
for(int i = 2; i <= n; i++) {
if(valid[i]) {
tot++;
ans[tot] = i;
}
for(int j = 1; ((j <= tot) && (i*ans[j]<=n)); j++) {
// printf("i = %d, j = %d, ans[j] = %d, i*ans[j] = %d\n", i, j, ans[j], i*ans[j]);
valid[i*ans[j]] = false;
if(i%ans[j] == 0) {
// printf("%d / %d = 0\n", i, ans[j]);
break;
}
}
}
//输出结果
for(int i = 1; i <= tot; i++) {
cout << ans[i] << " ";
}
cout << endl;
}
int main()
{
int n;
int tot = 0;
cin >> n;
getPrime(n, tot);
return 0;
}
数组valid[i]记录i是否为素数, 初始化所有的valid[i] 都为true.从2开始从小到大枚举i, 若valid[i]=true,则从i*i开始的每一个i的倍数valid[i]设置为false.结束之后valid[i] = true的就是素数。
#include
#include
#include
using namespace std;
const int maxn = 1000000;
bool valid[maxn];
//保存素数index=1开始
int ans[maxn];
void getPrime(int n, int &tot) {
memset(valid, true, sizeof(valid));
tot = 0;
int i, j;
for(i = 2; i <= n; i++) {
if(valid[i]) {
if(n/i < i) break;
for(j=i*i; j <= n; j+=i) {
valid[j] = false;
}
}
}
for(i=2; i <= n; i++) {
if(valid[i]) {
ans[++tot] = i;
}
}
for(i = 1; i <= tot; i++) {
cout << ans[i] << " ";
}
cout << endl;
}
int main()
{
int n;
int tot;
cin >> n;
getPrime(n, tot);
return 0;
}
4。质因数分解
给定一个整数N, 将N分解质因数
思路:N的质数要么是N本身(N是素数), 要么一定小于等于sqrt(N), 因此可用小于等于sqrt(N)的数对N进行试除 , 一直到不能除为止。这时候剩下的如果不是1,那就是N的最大的质因数。
#include
#include
#include
using namespace std;
const int maxn = 1000;
/**
质因数分解
时间复杂度O(sqrt(n))
n:待分解的整数
&tot 不同质因数的个数
数组a a[i] 表示第i个质因数
数组b b[i] 表示第i个质因数的质数
**/
void factor(int n, int a[], int b[], int &tot) {
int temp, i, now;
temp = (int)((double)sqrt(n)+1);
tot = 0;
now = n;
for(i = 2; i <= temp; ++i) {
if(now%i == 0) {
a[++tot] = i;
b[tot] = 0;
while(now%i == 0) {
++b[tot];
now/=i;
}
}
}
if(now != 1) {
a[++tot] = now;
b[tot] = 1;
}
}
int main()
{
int n;
int tot;
int a[maxn];
int b[maxn];
cin >> n;
factor(n, a, b, tot);
cout << a[1] << "^" << b[1];
for(int i = 2; i <= tot; i++) {
cout << "+" << a[i] << "^" << b[i];
}
return 0;
}