7-148 亲和数判断

古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:1+2+4+5+10+11+20+22+44+55+110=284。而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们称这样的数对为亲和数。也就是说,若两个数中任何一个数都是另一个数的真约数之和,则它们就是亲和数。请判断输入的两个整数是否是亲和数。

输入格式:

测试数据有多组,处理到文件尾。每组测试输入两个正整数a,b。

输出格式:

对于每组测试,若a,b是亲和数,是则输出“YES”,否则输出“NO”。引号不必输出。

输入样例:

220 284

输出样例:

YES

 代码如下:

#include<stdio.h>
int main()
{
	int a, b, c, d, e;
	while (scanf("%d%d", &a, &b) != EOF){
		for (c = 1, d = 0; c < a; c++){
			if (a % c == 0){
				d += c;
			}
		}
 
		for (c = 1, e = 0; c < b; c++){
			if (b % c == 0){
				e += c;
			}
		}
		if (d == b && e == a){
			printf("YES\n");
		}
		else{
			printf("NO\n");
		}
	}
	return 0;
}

### 关于亲和判断的PTA题目及其解法 #### 什么是亲和亲和是指两个整数 \(a\) 和 \(b\),如果它们各自的除自身以外的所有因之和等于对方,则称这两个是一对亲和。例如,\(220\) 和 \(284\) 是一对经典的亲和[^1]。 #### 判断亲和的核心算法判断是否为亲和,可以按照以下逻辑设计程序: 1. **计算一个的所有真因子(即除了它本身外的所有因子)并求和**。 2. **验证第一个的因子和是否等于第二个,以及第二个的因子和是否等于第一个**。 以下是具体的实现方法: ```python def sum_of_divisors(n): """ 计算 n 的所有真因子之和 """ total = 0 for i in range(1, int(n / 2) + 1): # 只需遍历到 n/2 即可找到所有真因子 if n % i == 0: total += i return total def are_amicable_numbers(a, b): """ 判断 a 和 b 是否为亲和 """ sum_a = sum_of_divisors(a) sum_b = sum_of_divisors(b) if (sum_a == b and sum_b == a) and a != b: # 确保两者不相等 return True return False # 测试案例 print(are_amicable_numbers(220, 284)) # 输出应为 True ``` 上述代码实现了如下功能: - `sum_of_divisors` 函用于计算给定的所有真因子之和[^2]。 - `are_amicable_numbers` 函则通过比较两个的因子和来判定它们是否构成亲和关系[^3]。 #### 时间复杂度分析 对于单次调用 `sum_of_divisors` 方法的时间复杂度为 \(O(\sqrt{n})\)[^4],因为只需要枚举至 \(\lfloor{\frac{n}{2}}\rfloor\) 来找出所有的因子。因此,在最坏情况下整个过程的时间复杂度大约为 \(O(\sqrt{a}+\sqrt{b})\)。 #### 提高效率的方法 为了进一步优化性能,可以通过预处理的方式存储较小范围内的所有的因子和,从而减少重复运算次。这种方法特别适合批量查询多个可能成为亲和的候选者的情况。 ```python MAX_LIMIT = 10000 divisor_sums = [0] * MAX_LIMIT for num in range(1, MAX_LIMIT): divisor_sum = sum(i for i in range(1, num//2 + 1) if num % i == 0) divisor_sums[num] = divisor_sum def find_all_amicables(limit=MAX_LIMIT): amicable_pairs = [] seen = set() for number in range(1, limit): pair_candidate = divisor_sums[number] if pair_candidate >= limit or pair_candidate == number: continue if divisor_sums[pair_candidate] == number and not(number in seen or pair_candidate in seen): amicable_pairs.append((number, pair_candidate)) seen.add(number) seen.add(pair_candidate) return amicable_pairs result = find_all_amicables(MAX_LIMIT) print(result[:5]) # 打印前五对亲和作为示例 ``` 此段代码展示了如何利用预先计算好的组快速查找一定区间内全部存在的亲和配对情况[^5]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小羊 : )

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

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

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

打赏作者

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

抵扣说明:

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

余额充值