The number of divisors(约数) about Humble Numbers HDU - 1492 (唯一分解定理)

本文介绍了一种计算特定类型数——谦逊数的因数数量的方法。谦逊数仅包含2、3、5或7作为其质因数。通过使用唯一分解定理,我们提供了一个高效的算法,用于确定任意给定谦逊数的因数总数。

A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, … shows the first 20 humble numbers.

Now given a humble number, please write a program to calculate the number of divisors about this humble number.For examle, 4 is a humble,and it have 3 divisors(1,2,4);12 have 6 divisors.

Input

The input consists of multiple test cases. Each test case consists of one humble number n,and n is in the range of 64-bits signed integer. Input is terminated by a value of zero for n.

Output

For each test case, output its divisor number, one line per case.

Sample Input

4
12
0

Sample Output

3
6

题意:

给一个数字n,求出n有多少个因数。

思路:

唯一分解定理:

一个大于1的正整数N,如果它的标准分解式为:,那么它的正因数个数为
N(n)=(1+a1)(1+a2)(1+a3)…(1+an)。

代码:

#include<stdio.h>
int main()
{
    long long n;
    while(~scanf("%lld",&n)&&n)
    {
        int a=1,b=1,c=1,d=1;
        while(n%2==0)
        {
            a++;
            n=n/2;
        }
        while(n%3==0)
        {
            b++;
            n=n/3;
        }
        while(n%5==0)
        {
            c++;
            n=n/5;
        }
        while(n%7==0)
        {
            d++;
            n=n/7;
        }
        printf("%d\n",a*b*c*d);
    }
    return 0;
}
# 题目重述 判断两个数是否为**亲和数对**(亲密数): 若 $ a \neq b $,且 $ a $ 的真约数之和等于 $ b $,$ b $ 的真约数之和等于 $ a $,则称它们是亲和数。 可以在不使用 `sumOfDivisors` 函数的情况下完成。 --- # 详解 在 C 语言中,**函数不是必须的**。我们可以将原本写在函数中的逻辑**直接嵌入主程序**,尤其是当题目较简单或只调用一次时。 下面我们将实现一个**不使用自定义函数**的版本,所有计算都在 `main` 函数中完成。 --- ### ✅ 核心思想不变: - 分别计算 $ A $ 和 $ B $ 的真约数- 判断是否满足亲和数条件 - 但这次不用函数封装,而是用代码块重复实现“求真约数和” --- ### ✅ 不使用函数的完整 C 语言代码 ```c #include <stdio.h> int main() { int M; scanf("%d", &M); // 测试实例数量 while (M--) { int A, B; scanf("%d %d", &A, &B); // 如果两数相等或小于等于1,直接排除 if (A == B || A <= 1 || B <= 1) { printf("NO\n"); continue; } // 计算 A 的真约数和 int sumA = 0; for (int i = 1; i * i <= A; i++) { if (A % i == 0) { if (i != A) sumA += i; // 添加 i,只要不是 A 自身 int other = A / i; if (other != A && other != i) { // 避免重复添加 sqrt(A) 和自身 sumA += other; } } } // 计算 B 的真约数和 int sumB = 0; for (int i = 1; i * i <= B; i++) { if (B % i == 0) { if (i != B) sumB += i; // 添加 i,只要不是 B 自身 int other = B / i; if (other != B && other != i) { // 避免重复添加 sumB += other; } } } // 判断是否为亲和数 if (sumA == B && sumB == A) { printf("YES\n"); } else { printf("NO\n"); } } return 0; } ``` --- ### 🔍 代码说明(无函数版) 1. **没有定义 `sumOfDivisors` 函数** - 而是把“求真约数和”的逻辑复制了两次: - 一次用于 $ A $ - 一次用于 $ B $ 2. **如何避免加到自身?** - 在加约数时判断:`if (i != A)` 和 `if (other != A)` - 并且 `other != i` 避免平方根重复添加 3. **为什么可以不用函数?** - 因为 C 允许在 `main` 中直接写循环和判断 - 虽然代码略显重复(违反“DRY 原则”),但在竞赛或简单题中可接受 4. **效率与正确性** - 时间复杂度仍为 $ O(\sqrt{n}) $ 每个数 - 正确处理了边界情况(如 1、相同因子等) --- ### 🧪 示例输入输出 **输入:** ``` 2 220 284 100 200 ``` **输出:** ``` YES NO ``` --- # 知识点(列出解答该问题需要的知识点) - **真约数求和**:遍历 $1$ 到 $\sqrt{n}$,成对添加约数,提升效率。 - **亲和数判定条件**:两数互异,且各自真约数和等于对方。 - **边界处理**:排除 $A = B$ 或小于等于1的情况,避免误判。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值