洛谷 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

 屠龙宝刀点击就送

经过2.9G打表发现 

rabbit number的各位数字一定<=3

#include <cstdlib>
#include <cstdio>
#include <stack>
#include <cmath>

typedef long long LL;
using namespace std;

int maxn,L,R,l,d[200],i,ans;
LL geth(LL f)
{
    LL h=0;
    while(f)
    {
        h+=f%10;
        f/=10;
    }
    return h;
}
LL powe(LL a,LL b)
{
    LL base=a,r=1;
    while(b)
    {
        if(b&1)
        r*=base;
        base*=base;
        b>>=1;
    }
    return r;
}
void get(LL &x)
{
    x=0;
    for(i=1;i<=l;++i)
    x=x*10+d[l-i+1];
}
void wamn()
{
    LL n;
    get(n);
    if(n>R)
    {
        printf("%d",ans);
        exit(0);
    }
    LL m=powe(n,2);
    LL x=geth(n),y=geth(m);
    if(x*x==y) ans++;
    d[1]++;
    int k=1;
    while(d[k]>3)
    {
        d[k+1]+=1;
        d[k]=0;
        l=max(l,k+1);
        k++;
    }
    wamn();
}
int main()
{
    scanf("%d%d",&L,&R);
    while(L)
    {
        d[++l]=L%10;
        L/=10;
    }
    wamn();
}
View Code

终究因为洛谷数据太弱 我的代码才能过

放到codevs上大数据会蹦。。

终究因为我

void get(LL &x)
{
    x=0;
    for(i=1;i<=l;++i)
    x=x*10+d[l-i+1];
}

这段代码每次递归都要读一次 太浪费时间

然后借鉴了同学做法,效率更高。 思想是一样的

#include <algorithm>
#include <cstdio>

using namespace std;

int an[25500],maxn,L,R,l,cnt,i,Ans;
void find(int x,int y,int z)
{
    long long a=x;
    a=a*a;int b=0;
    if(x>=L&&x<=R)
    {
        while(a){b+=a%10;a/=10;}
        if(y*y==b) an[++cnt]=x;
    }
    if(z>R) return;
    for(int i=0;i<4;++i)
    find(x*10+i,y+i,z*10);
}
int main()
{
    scanf("%d%d",&L,&R);
    find(0,0,1);
    sort(an+1,an+cnt+1);
    for(i=1;i<=cnt;++i)
    if(an[i-1]!=an[i])
    Ans++;
    printf("%d",Ans);
    return 0;
}
View Code
posted @ 2017-02-26 08:25  杀猪状元  阅读(338)  评论(0编辑  收藏  举报