2020牛客寒假算法基础集训营1 E题

rin和快速迭代

https://ac.nowcoder.com/acm/contest/3002/E

这道题说实话并不难 主要是如何快速求出因子的个数
先把题目贴下来
链接 https://ac.nowcoder.com/acm/contest/3002/E

rin最近喜欢上了数论。 然而数论实在太复杂了,她只能研究一些简单的问题。 这天,她在研究正整数因子个数的时候,想到了一个“快速迭代”算法。设 为 的因子个数,将 迭代下去,rin猜想任意正整数最终都会变成 。 例如: 。 她希望你帮她验证一下。她会给你一个正整数 ,让你输出它在迭代过程中,第一次迭代成 的迭代次数。

输入描述:
一个正整数 n(3<n<1e12)
请在这里输入引用内容

输出描述:
一个正整数,为n迭代至2的次数。

示例1
输入
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次。

但是我在这题卡了很久 超时很多次 说白了就是菜
先讲下做法 穷举加剪枝
先上代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll f(ll x){             //求x的因子个数
    ll i,res=0;
    for(i=1;i*i<x;i++){
        if(x%i==0)res+=2;
    }
    return res+(i*i==x);
}
int main(){
    ll i=0,n;
    cin>>n;
    while(n!=2)n=f(n),i++;
    cout<<i;
}

讲一下怎么剪枝 举个例子
16的因子有 1 2 4 8 16 看这个所有的因子都分在开根号的两边 而且个数相同
再看12 有 1 2 3 4 6 12 ,12开根号为2根号3 大于三小于4
这样可以有效的剪枝 在穷举的时候让i*i小于x就行 除了找到一个就乘二 然后若是开根号正好为一个整数就在加上这个数

还有一种做法 比较取巧 说实话我是完全不知道可以这样做的
先上代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

long long dcp(long long x){ 
    long long i,ans = 1;
    for(i = 2; i * i <= x; i++){
        if(x % i == 0){
            long long temp = 0;
            while(x % i == 0){
                x /= i;
                temp++;
            }
            ans *= (temp+1);
        }
    }
    if(x > 1) ans *= 2;
    return ans;
}
int main(){
    long long n,count=0;
    scanf("%lld",&n);
    while(n!=2){
        n=dcp(n);
        count++;
    }
    printf("%d\n",count);
    return 0; 
}

对着这个图片看下应该能看懂 来自zt大佬的手笔
图片说明

全部评论

相关推荐

05-24 14:12
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务