1. 程式人生 > >luogu P1362 兔子數 x

luogu P1362 兔子數 x

print 得出 printf define math 思路 數據 main 大量

P1362 兔子數

題目描述

設 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

思路:

  1.首先看數據範圍(1 <= L <= R <= 10^9),這說明最大的數S(a*a)一定會比18*9(162)要小(因為S是加和嘛~),所以S(a)就一定會比13要小,因為13*13=169(稍微>162),所以不可能會比13要大.

  2.因為經過大量實(打)驗(表)之後得出每一個兔子數的每一位上的數一定會<=3,因為如果某數字x的一位a>=4.那麽它在該位的貢獻是a^2的 但是在 x 中這一位自乘進了一位 故貢獻為 a^2/10+a^2%10

  3.那麽這道題的思路就很明了了:

            搜索+剪枝就好.

坑點:

  要記得排次序,不能夠直接輸出cnt!!!

上代碼:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include 
<cmath> #define LL long long using namespace std; int L,R,cnt,ANSWER; int ans[30000]; void build(int x,int y,int z) { LL a=x; a=a*a; int b=0; if(x>=L && x<=R)///在區間之內 { while(a) { b+=a%10; a/=10; } if(y*y==b)///尋找滿足條件的數,並進行儲存 ans[++cnt]=x; } ///停止的條件 if(z>R) return; for(int i=0;i<4;i++) build(x*10+i,y+i,z*10); } int main() { scanf("%d%d",&L,&R); build(0,0,1); /* for(int i=1;i<=cnt;i++) printf("%d ",ans[i]); printf("\n"); printf("--------------------------\n"); */ sort(ans+1,ans+1+cnt); /* for(int i=1;i<=cnt;i++) printf("%d ",ans[i]); printf("\n"); */ for(int i=1;i<=cnt;i++) { if(ans[i-1]!=ans[i]) ANSWER++; } printf("%d",ANSWER); return 0; }

luogu P1362 兔子數 x