兔子数
题目描述
设 S(N ) 表示 N 的各位数字之和,如 S(484) = 4+8+4 = 16, S(22) = 2+2 = 4。如果一个正整数满足 S(x*x) = S(x) *S(x),我们称之为 Rabbit N umber。比方说,22 就是一个 Rabbit N umber,因为 S(484) = S(22) *S(22)。
现在,给出一个区间 [L, R],求在该区间内的 Rabbit N umber 的个数。
输入输出格式
输入格式:
输入仅一行,为空格隔开的两个数 L 和 R。
输出格式:
输出仅一行一个整数,表示所求 Rabbit N umber 的个数。
输入输出样例
输入样例#1:
样例1:22 22 样例2:484 484 样例3:1 58 样例4:58 484 样例5:1000000000 1000000000
输出样例#1:
样例1:1 样例2:0 样例3:12 样例4:24 样例5:1
说明
1 <= L <= R <= 10^9
思路:打表找规律。
不知道为什么,由0~3构造数据即可。
代码实现:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int l,r,ans; 5 int s[20010],n; 6 void find(int x,int y,int z){ 7 long long a=x; 8 a=a*a; 9 int b=0; 10 if(x>=l&&x<=r){ 11 while(a){b+=a%10;a/=10;} 12 if(y*y==b) s[++n]=x; 13 } 14 if(z>r) return; 15 for(int i=0;i<4;i++) 16 find(x*10+i,y+i,z*10); 17 } 18 int main(){ 19 scanf("%d%d",&l,&r); 20 find(0,0,1); 21 sort(s+1,s+n+1); 22 for(int i=1;i<=n;i++) 23 if(s[i]!=s[i-1]) ans++; 24 printf("%d\n",ans); 25 return 0; 26 }
其实不用在意我的代码,自己写个深搜,把for(1~9)换成for(0~3)就行了。
另外我的同学有一种很巧妙的方法,优化枚举,每位满四进一。
其实也挺好实现的。
1 #include<cstdio> 2 int l,r,ans,a,b,d; 3 long long c; 4 int ame(int x,int y){ 5 for(y;y<=x;y*=10) if(x/y%10>3) return (x/y/10+1)*10*y; 6 return x; 7 } 8 int main(){ 9 scanf("%d%d",&l,&r); 10 for(int i=l;i<=r;i++){ 11 if(i%10>3) i=(i/10+1)*10; 12 i=ame(i,1); 13 a=i,b=0,c=i,d=0;c=c*c; 14 while(a){b+=a%10;a/=10;} 15 while(c){d+=c%10;c/=10;} 16 if(b*b==d&&i<=r) ans++; 17 } 18 printf("%d\n",ans); 19 return 0; 20 }
题目来源:洛谷