神奇的魔法数

神奇的魔法数

1000ms
32768KB
This problem will be judged on FZU. Original ID:  1896
64-bit integer IO format:  %I64d      Java class name:  Main
Font Size:   
Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  • John定义了一种“神奇的魔法数”。 不含前导零且相邻两个数字之差至少为m的正整数被称为“神奇的魔法数”。特别的,对于任意的m,数字1..9都是“神奇的魔法数”。
    John想知道,对于给定的m,在正整数a和b之间,包括a和b,总共有多少个“神奇的魔法数”?

    Input

    第一行一个数字T(1<=T<=100),表示测试数据组数。
    接下来T行,每行代表一组测试数据,包括三个整数a,b,m。(1<=a<=b<=2,000,000,000, 0<=m<=9)

    Output

    对于每组测试数据,输出一行表示“神奇的魔法数”的个数。

    Sample Input

    7
    1 10 2
    1 20 3
    1 100 0
    10 20 4
    20 30 5
    1 10 9
    11 100 9
    

    Sample Output

    9
    15
    100
    5
    3
    9
    1
    

    Source

    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<algorithm>
    using namespace std;
    int dp[11][10];  /// 位数  首位
    int m;
    void fun()
    {
        memset(dp,0,sizeof(dp));
        for(int i=0; i<=9; i++)
            dp[1][i]=1;
        for(int i=2; i<=10; i++)
            for(int j=0; j<=9; j++)
                for(int k=0; k<=9; k++)
                    if(abs(j-k)>=m)
                        dp[i][j]+=dp[i-1][k];
    }
    int slove(int x)
    {
        int len=0,sum=0,bit[15];
        while(x)
        {
            bit[++len]=x%10;
            x=x/10;
        }
        for(int i=1; i<len; i++) ///处理最高位的后面位 len-1  位
            for(int j=1; j<10; j++)
                sum+=dp[i][j];
        for(int i=1; i<bit[len]; i++) /// 处理最高位 下不同的首位
            sum+=dp[len][i];
        for(int i=len-1; i>0; i--)  /// 在处理相邻为 
        {
            for(int j=0; j<bit[i]; j++)
                if(abs(j-bit[i+1])>=m)
                    sum+=dp[i][j];
            if(abs(bit[i]-bit[i+1])<m)
                break;
        }
        return sum;
    }
    int main()
    {
        int t,a,b;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&a,&b,&m);
            fun();
            printf("%d\n",slove(b+1)-slove(a));
        }
        return 0;
    }


    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值