#include <iostream>
#include <iomanip>
using namespace std;
/*
求500万以内的所有亲和数 如果两个数a和b,a的所有真因数之和等于b,
b的所有真因数之和等于a,则称a,b是一对亲和数。
例如220和284,1184和1210,2620和2924。
真因数:不包含本身的所有因数
220的真因子是:1、2、4、5、10、11、20、22、44、55、110;
284的真因子是:1、2、4、71、142。
而这两个数恰恰等于对方的真因子各自加起来的和
*/
void TestQinHeShu();
// 求公因数之和:
// 对于i:如果n是i的倍数,则将sum[n]+=i;
// 关键还是真因数的生成算法。。。
void QinHeShu(unsigned num);
// 预处理
void QinHeShuPreProcess(int *arr, unsigned num);
void FindResults(int *arr, unsigned num);
// 求从1到num内的所有质数
void ZhiShu(unsigned num);
void ZhiShuPreProcess(bool *arr, unsigned num);
void ZhiShuPrintResult(bool *arr, unsigned num);
#include "6_QinHeShu.h"
void TestQinHeShu()
{
int num = 1000000;
ZhiShu(num);
}
void QinHeShu(unsigned num)
{
int *res = new int[num + 1];
QinHeShuPreProcess(res, num);
FindResults(res, num);
delete []res;
}
void QinHeShuPreProcess(int *arr, unsigned num)
{
for (unsigned i = 0; i <= num; ++i)
{
arr[i] = 1;
}
for (unsigned i = 2; i + i <= num; ++i)
{
unsigned j = i + i;
while (j <= num)
{
arr[j] += i;
j += i;
}
}
}
void FindResults(int *arr, unsigned num)
{
// arr[i] == j && arr[j] == i;
// 我哭了... arr[arr[i]] == i
for (unsigned i = 1; i <= num; ++i)
{
unsigned yinzi = arr[i];
if (arr[yinzi] == i)
{
cout << i << " : " << yinzi << endl;
}
}
}
void ZhiShu(unsigned num)
{
bool *arr = new bool[num + 1];
ZhiShuPreProcess(arr, num);
ZhiShuPrintResult(arr, num);
delete []arr;
}
void ZhiShuPreProcess(bool *arr, unsigned num)
{
for (unsigned i = 0; i <= num; ++i)
{
arr[i] = true;
}
// 如果是合数,则设置为false
for (unsigned i = 2; i + i <= num; ++i)
{
unsigned j = i + i;
while (j <= num)
{
arr[j] = false;
j += i;
}
}
}
void ZhiShuPrintResult(bool *arr, unsigned num)
{
// 每行8个
int total = 0;
int current = 0;
for (unsigned i = 2; i <= num; ++i)
{
if (arr[i])
{
total++;
current++;
if (current % 8 == 0)
{
cout << setw(8) << i << endl;
current = 0;
}
else
{
cout << setw(8) << i << " ";
}
}
}
cout << "一共 " << total << " 个质数" << endl;
}