寻找亲和数对**

所谓亲和数对,是指两个不同的自然数,其中任何一个数的真因数之和都恰好等于另一个数。例如:220 和 284 就是一对亲和数对。

220 的全部真因数包括:1、2、4、5、10、11、20、22、44、55、110, 它们的和恰为 284;
284 的全部真因数包括:1、2、4、71、142,它们的和也恰好为 220。

据说,两个好朋友佩带写有亲和数对的护身符可使两人保持良好的友谊。

请编写程序,输入区间的下限和上限,若该区间内存在亲和数对,则输出区间内的全部亲和数对,否则输出 None。

输入格式:

两个正整数 a 和 b,且 a ≤ b ≤ 100000000,即区间 [a, b] 的下限和上限

输出格式:

若存在亲和数对,则输出若干行,每行一个亲和数对,均在区间 [a, b] 内,且前者小于后者,两者以空格间隔;否则输出 None。

输入样例1

1000 3000

输出样例1

1184 1210
2620 2924

输入样例2

7000 9000

输出样例2

None

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

此代码为csnd上以一位大佬写的c++的改编成c语言的,并非完全原创!!


#include<stdio.h>

int sum[5000010];   //为防越界

int main()
{
    int i, j,a,b,count=0;
    scanf("%d%d",&a,&b);
    for (i = 0; i <= 5000000; i++)
        sum[i] = 1;  //1是所有数的真因数所以全部置1

    for (i = 2; i + i <= 5000000; i++)  //预处理,预处理是logN(调和级数)*N。
        //@litaoye:调和级数1/2 + 1/3 + 1/4......的和近似为ln(n),
        //因此O(n *(1/2 + 1/3 + 1/4......)) = O(n * ln(n)) = O(N*log(N))。
    {
        //5000000以下最大的真因数是不超过它的一半的
        j = i + i;  //因为真因数,所以不能算本身,所以从它的2倍开始
        while (j <= 5000000)
        {
            //将所有i的倍数的位置上加i
            sum[j] += i;
            j += i;
        }
    }

    for (i =a; i <=b; i++)   //扫描,O(N)。
    {
        // 一次遍历,因为知道最小是220和284因此从220开始
        if (sum[i] > i && sum[i] <= 5000000 && sum[sum[i]] == i)
        {
            //去重,不越界,满足亲和
            printf("%d %d\n",i,sum[i]);
            count++;
        }
    }
    if(count==0)
        printf("None");
    return 0;
}

 

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮央乜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值