hdu 2089 不要62 基础数位DP

来源:互联网 发布:php获取js变量的方法 编辑:程序博客网 时间:2024/04/28 21:48



不要62

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32198    Accepted Submission(s): 11432


Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
 

Input
输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
 

Output
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
 

Sample Input
1 1000 0
 

Sample Output
80
 

Author
qianneng
 

Source
迎接新学期——超级Easy版热身赛
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  2094 2090 2091 2093 2092 
 

Statistic | Submit | Discuss | Note


#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn=1000000    ;const int maxL=7;int dp[9][3];//dp[x][0]表示长度为x,且不存在62或4的个数//dp[x][1]表示长度为x, 且不存在62或4,开头为2的个数//dp[x][2]表示长度为x,且存在62或4的个数int bit[11];//存放每一位的数字,bit[0]表示位数void pre(){    dp[0][0]=1;//dp[0][1]=dp[0][2]=0;    for(int len=1;len<=6;len++)    {        dp[len][0]=  9*dp[len-1][0]-dp[len-1][1];/*        最高位上0到9,但不能选4,再减去最高位为6并且次高位为2的情况*/        dp[len][1]=  dp[len-1][0];        /*最高位上直接加2*/        dp[len][2]= 10*dp[len-1][2]+  dp[len-1][0]+dp[len-1][1];        /*如果最高位之前已经存在那么最高位取0到9,否则最高位取4,或者最高位取6但是次高位取2。*/    }}int work(int x)//[1,x)内不存在62或4的个数 还要+1,就是x自己。{    bit[0]=0;    int t=x;    while(t)    {        bit[++bit[0]]=t%10;        t/=10;    }    bit[bit[0]+1]=0;//为了配合后面的判断语句    int cal=0;bool has=0;//最后cal代表区间[1,x]内存在4或者62的个数,has代表数x的前面是否已经存在4或62    for(int i=bit[0];i>=1;i--)//从高位到低位,计算每一位时,当前位取的应该是[0,bit[i]),这样保证了比x小。    {        cal+=bit[i]*dp[i-1][2];//当前位取[0,bit[i]),先让算上后面存在62或4的,这样整个数一定存在。        if(has) cal+=bit[i]*dp[i-1][0];//如果前面已经存在了,那么后面还要补一种就是不存在62或4的        else        {            if(bit[i]>4)  cal+= dp[i-1][0];//当前位如果为4的情况在之前已经考虑过了            if(bit[i+1]==6&&bit[i]>2)  cal+=dp[i][1];            if(bit[i]>6)  cal+=dp[i-1][1];        }        if(bit[i]==4||bit[i+1]==6&&bit[i]==2)  has=true;    }    return x-cal;}int main(){    pre();    int le,ri;    while(~scanf("%d%d",&le,&ri)&&(le||ri))    {        printf("%d\n",work(ri+1)-work(le));    }    return 0;}


0 0