HDU 2089 不要62

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2089 不要62相关的知识,希望对你有一定的参考价值。

刚学的数位DP。

dp[i][j]表示,长度为i的数字,并且最高位为j的情况下的吉利的数字有几个

很显然dp[i][j]是由dp[i-1][0,1,2,3,.....9]推导而来的

处理出dp数组之后,我们能在o(1)效率内得到以某个数字开头的数字有几个

举个例子:

假设我们现在需要计算的是235--990000之间有几个吉利的数字

我们很快能得到200--999999之间的数字有几个,dp数组已经预处理好了,累加即可

剩下的就是把200--234之间的吉利数字个数乙级990001--999999之间的吉利数字个数删除,这一步暴力即可

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <string>
using namespace std;

//dp[i][j]表示,长度为i的数字,并且最高位为j的情况下的吉利数字的个数
int dp[15][15];
int p[15];
int tot;
int a,b;

bool f(int x)
{
    tot=0;
    while(x)
    {
        p[tot++]=x%10;
        x=x/10;
    }
    for(int i=0; i<tot/2; i++) swap(p[i],p[tot-i-1]);

    for(int i=0; i<tot; i++) if(p[i]==4) return 1; //是不吉利数
    for(int i=1; i<tot; i++) if(p[i-1]==6&&p[i]==2) return 1; //是不吉利数
    return 0;//不是不吉利数
}

void init()
{
    memset(dp,0,sizeof dp);
    for(int i=0; i<=9; i++) dp[1][i]=1;
    dp[1][4]=0;
    for(int i=2; i<=7; i++)
    {
        for(int j=0; j<=9; j++)
        {
            if(j==4) //这一位是4,那么GG
            {
                dp[i][j]=0;
                continue;
            }
            for(int k=0; k<=9; k++) //从第i-1位的0--9推导过来
            {
                if(j==6&&k==2) continue;//这一位是6,上一位是2 GG
                else dp[i][j]=dp[i][j]+dp[i-1][k]; //个数累加上去
            }
        }
    }
}

int main()
{
    init();
    while(~scanf("%d%d",&a,&b))
    {
        if(!a&&!b) break;

        int tmp;
        int lena=0,firsta;
        int lenb=0,firstb;

        tmp=a;
        while(tmp) lena=lena+1, firsta=tmp%10, tmp=tmp/10;
        tmp=b;
        while(tmp) lenb=lenb+1, firstb=tmp%10, tmp=tmp/10;

        int ans=0;
        bool fail=0;
     //   printf("---%d %d\n",lena,firsta);

      //  printf("---%d %d\n",lenb,firstb);

        for(int i=lena; i<=lenb; i++)
        {
            if(fail==0)
            {
                if(i==lena)
                    for(int j=firsta; j<=9; j++)
                    {
                        if(i==lenb&&j>firstb) {fail=1; break;}
                        ans=ans+dp[i][j];
                    }
                else if(i==lenb)
                    for(int j=1; j<=firstb; j++)
                    {
                        if(i==lenb&&j>firstb) {fail=1; break;}
                        ans=ans+dp[i][j];
                    }

                else
                    for(int j=1; j<=9; j++)
                    {
                        if(i==lenb&&j>firstb) {fail=1; break;}
                        ans=ans+dp[i][j];
                    }
            }
        }

        for(int i=0; i<lena-1; i++) firsta=firsta*10;
        for(int i=0; i<lenb-1; i++) firstb=firstb*10+9;

        for(int i=firsta; i<=a-1; i++) if(f(i)==0) ans--;
        for(int i=b+1; i<=firstb; i++)  if(f(i)==0) ans--;

        printf("%d\n",ans);
    }

    return 0;
}

 

以上是关于HDU 2089 不要62的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2089 不要62

HDU 2089 不要62

HDU 2089 —— 不要62

[HDU2089]不要62

hdu2089 不要62

HDU 2089 不要62