她在研究正整数因子个数的时候,想到了一个“快速迭代”算法

链接:https://ac.nowcoder.com/acm/contest/3002/E
题目描述
rin最近喜欢上了数论。
然而数论实在太复杂了,她只能研究一些简单的问题。
这天,她在研究正整数因子个数的时候,想到了一个“快速迭代”算法。设 f(x) 为 x 的因子个数,将 f(x) 迭代下去,rin猜想任意正整数最终都会变成 。
例如:f(12) = 6, f(6) = 4, f(4) = 3, f(3) = 2 。
她希望你帮她验证一下。她会给你一个正整数 n,让你输出它在迭代过程中,第一次迭代成 2 的迭代次数。
输入描述:
一个正整数 n (3 <= n <= 10^12)
输出描述:
一个正整数,为 n 迭代至 2 的次数。
示例
输入
12
输出
4
说明
12的因子:1,2,3,4,6,12。共6个。
6的因子:1,2,3,6。共4个。
4的因子:1,2,4。共3个。
3的因子:1,3。共2个。
12 → 6 → 4 → 3 → 2 , 故迭代了4次。

搬运
唯一分解定理
一个数n肯定能被分解成 在这里插入图片描述. 因为一个数肯定是由合数和质数构成的,合数又可以分解成质数和合数,最后递归下去就会变成质数的乘积。比如36 -> 223*3 -> 2^2 * 3^2 .
最后化成了质数相乘的形式。
在这里插入图片描述
其中 (2)中运用等比数列求和公式可化简为:
在这里插入图片描述

本题可以应用公式: n的因子个数 = (1+a1)(1+a2)…(1+an)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <math.h>
#include <map>

using namespace std;
typedef long long ll;

ll cnt(ll n)  //求 n 的因子个数
{
    ll i, ans = 1, a;
    for(i = 2; i*i <= n; i++)
    {
        if(n%i == 0)
        {
            a = 0;
            while(n%i == 0)
            {
                n /= i;
                a++;
            }
            ans *= (a+1);
        }
    }
    if(n > 1)
        ans *= 2;
    return ans;
}

int main()
{
    ll n, i, tmp;
    while(~scanf("%lld", &n))
    {
        tmp = cnt(n);
        i = 1;
        while(tmp != 2)
        {
            tmp = cnt(tmp);
            i++;
        }
        printf("%lld\n", i);
        }
    return 0;
}

cnt()函数看的大神的代码,真是个神奇的写法,一开始还不懂为什么 “if(n > 1) ans *= 2; ” ,觉得最后一定有 n == 1, 所以输出中间过程看了一下(如下图),发现原来不是啊。比如520 = 2^3 * 5^1 * 13^1, 所以在素数13的那层循环里,找不到的n%i == 0, 13的指数 1 就要放到最后去乘
在这里插入图片描述

当然,函数的部分也可以直接放在main()里, 用一个while 循环

int main()
{
    ll n, i, ans, a;
    int cnt;
    while(~scanf("%lld", &n))
    {
        cnt = 0;
        while(n != 2)
        {
            cnt++;
            ans = 1;
            for(i = 2; i*i <= n; i++)
            {
                if(n%i == 0)
                {
                    a = 0;
                    while(n%i == 0)
                    {
                        n /= i;
                        a++;
                    }
                    ans *= (a+1);
                }
            }
            if(n > 1)
                ans *= 2;
            n = ans;
        }
        printf("%d\n", cnt);
    }
    return 0;
}

然后,求因子个数还可以

ll cnt(ll n)
{
    ll i, ans;
    ans = 0;
    for(i = 1; i*i <= n; i++)
        if(n%i == 0)
            ans += 2;
    i--;
    if(i*i == n)
        ans--;
    return ans;
}

显然这是一个伪原创,参考多方文章,但对这个题不好说是转载,就投了原创(捂脸),如有侵权,及时联系

发布了4 篇原创文章 · 获赞 0 · 访问量 123

猜你喜欢

转载自blog.csdn.net/xiongshuxian2019/article/details/104215065
今日推荐