古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:
1+2+4+5+10+11+20+22+44+55+110=284。
而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
你的任务就编写一个程序,判断给定的两个数是否是亲和数
Input
输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000 ;
Output
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。
Sample Input
2 220 284 100 200
Sample Output
YES NO
————————————————
这道题我刚拿到的思路是整体方向往判断素数的方向走,遍历能不能整除,如果能就将除数和被除数加起来,然后判断是否与另一个数相等即可。
代码如下:
#include <stdio.h>
#include <math.h>
int func(int x)
{ //重点是函数部分
int ret = 0;
int p = 0;//p是商
//真约数我们一次加两个值,除数和商
for (int i = 1; i < sqrt(x); i++)
{ //用一个sqrt()函数,只用求一半的值就行,减少运算
if (x % i == 0)//如果为0那就说明有真约数
{
p = x / i;//得到了商
ret += i + p;然后除数与商相加,并且让ret不断的相加
}
}
//这里还要注意一点,我们得到的真约数的和是包含这个数本身的,而题目上要求约数不能是自身
//然后我们再 ret=ret-x,减去他本身即可,最后返回ret
ret = ret - x;
return ret;
}
int main()
{
int n = 0;
scanf("%d", &n);
int j, k;
while (n--)//这里我一开始用的是while(scanf("%d", &n)!=EOF),但是我又不知道题上输完
//两组程序后,程序要不要结束,为了更接近题意,我改成了n--
{
scanf("%d %d", &j, &k);//按题目要求输入两个数
//这里的程序是改进过的,原来用的是两个for循环,然后听学长建议,改成了函数的形式
int tmp1 = func(j);//返回真约数的和
int tmp2 = func(k);
if (tmp1 == k && tmp2 == j)判断
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
这道题我的思路就是这样,如果大家还有不同的解法,也欢迎大家及时提出,我们互相学习,互相进步,谢谢大家!