神奇的魔法数

来源:互联网 发布:微博上淘宝优惠券 编辑:程序博客网 时间:2024/04/26 23:07

神奇的魔法数

1000ms
32768KB
This problem will be judged on FZU. Original ID: 1896
64-bit integer IO format: %I64d      Java class name: Main
Prev Submit Status Statistics Discuss Next
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

71 10 21 20 31 100 010 20 420 30 51 10 911 100 9

Sample Output

9151005391

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