【数论】Codevs1189Rabbit Number

来源:互联网 发布:python随机数求和 编辑:程序博客网 时间:2024/06/15 17:01
题目描述 Description

设S(N)表示N 的各位数字之和,如S(484)=4+8+4=16,S(22)=2+2=4。
如果一个正整数满足S(x*x)=S(x)*S(x),我们称之为Rabbit Number。比方说,
22 就是一个Rabbit Number,因为S(22*22)=S(22)*S(22)。
现在,给出一个区间[L;R],求在该区间内的Rabbit Number 的个数。

输入描述 Input Description

输入仅一行,为空格隔开的两个数L 和R

输出描述 Output Description

输出仅一行一个整数,表示所求Rabbit Number 的个数。

样例输入 Sample Input

样例数据1

22 22

样例数据2

484 484

样例数据3

1 58

样例数据4

58 484

样例数据5

1000000000 1000000000

样例输出 Sample Output

样例数据1

1

样例数据2

0

样例数据3

12

样例数据4

24

样例数据5

1

数据范围及提示 Data Size & Hint

数据限制
1<=L<=R<=10^9
打表之后找到规律:所有兔子数的每一位都在0-3四个数字之间,所以一位位数字搜就好了0-0
关于证明后来看了题解才知道
rabbit number的各位数字一定<=3
若某数字x的一位,a>=4
那么它在该位的贡献是a^2的
而在x中该位自乘进了一位
故贡献为a^2-10+1
导致s(x^2)<s(x)*s(x)
所以一定不是rabbit number
既然各位数字<=3
剩下的就是爆搜了
也可以打表+二分
来自TYVJ题解区
 

#include<cstdlib> #include<iostream>#include<cstdio> using namespace std; int L, R; long long S(long long x) { int ans = 0;while (x > 0) ans += x%10, x /= 10;return ans; } int cal(int cur) { int ans = 0;for (int i=0; i<4; i++) { long long x = cur*10 + i; if (x == 0 || S(x*x) != S(x)*S(x)) continue; if (L <= x && x <= R) ans ++; if (x <= R/10) ans += cal(x); } return ans;} int main() { cin>>L>>R; cout<<cal(0)<<endl; } 


 

0 0