1 条题解

  • 0
    @ 2025-8-24 22:16:17

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Wind_Smiled
    风颜悦。颜悦因风起,风起故颜悦。||向着不同的方向、我们逐渐远去、背对背的你我、难能再见||这个OP的 uid:266896259

    搬运于2025-08-24 22:16:17,当前版本为作者最后更新于2022-09-14 15:22:40,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意

    对于一个正整数 nn,定义 f(n)\operatorname{f}(n) 为它每一位数字的平方的和。

    现在给定三个正整数 k,a,bk,a,b,请求出满足 anba\le n\le bk×f(n)=nk\times \operatorname{f}(n)=nnn 的个数。

    对于 100%100\% 的数据,1k,a,b10181\le k,a,b\le 10^{18}aba\le b

    思路

    1. 模拟函数 f(n)\operatorname{f}(n) 对一个数的操作过程。
    2. 重复枚举可能的值,累加答案。

    方案一:纯暴力枚举

    nn 的值从 aabb 进行枚举,累加可能值的个数。

    但是根据数据范围:1k,a,b10181\le k,a,b\le 10^{18}aba\le b,所以 TLE 是不可避免的。

    方案二:优化

    由题意得:f(n)\operatorname{f}(n) 中,nn 的取值范围在 aabb 之间,令 aa 取最小值,bb 取最大值时, nn 的值最大,极限取值为:10181=9999999999999999910^{18}-1=99999999999999999,此时的 f(n)\operatorname{f}(n) 的值为 92×18=14589^2\times18=1458

    为方便计算,得出公式:

    由题意 k×f(n)=nk\times \operatorname{f}(n)=n

    因为两数相等,则每一位相等。

    所以 $\operatorname{f}(k\times \operatorname{f}(n))=\operatorname{f}(n)$。

    1114581458 模拟 f(n)\operatorname{f}(n) 即可,循环条件为 f(n)×kb\operatorname{f}(n) \times k \le b

    但是,最后个数会多计算 f(n)<a\operatorname{f}(n)<a 时的一些数,所以,令满足 f(n)a1\operatorname{f}(n) \le a-1ansans 逐个减一。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    long long k,a,b,sum,ans;
    long long f(long long x){
        long long ans=0;
        while(x!=0){
            ans+=(x%10)*(x%10);
            x/=10;
        }
        return ans;
    }
    int main(){
        cin>>k>>a>>b;
        for(int i=1;i<=1458&&i*k<=b;i++){
            if(f(i*k)==i){
                ans++;
            }
        }
        for(int i=1;i<=1458&&i*k<=a-1;i++){
            if(f(i*k)==i){
                ans--;
            }
        }
        cout<<ans;
        return 0;
    }
    
    • 1

    信息

    ID
    4998
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者