您的位置:首页 > 其它

hdu 3555 Bomb 炸弹(数位DP,入门)

2015-05-23 16:47 357 查看
题意:

  给一个数字n,求从1~n中有多少个数是含有49的,比如49,149,1490等都是含49的。

思路:

  2^64也顶多是十进制的20多位,那么按十进制位来分析更简单。如果能计算k位十进制数中分别有多少个含49的,那么计算就简单了。

  首先要求关于十进制位的一些信息,比如:i位的十进制数包含49有多少个,不包含49的多少个(除掉最高位是9的数量),不包含49但是最高位是9的有多少个(因为可能和更高一位组合成49)。注意精度,注意爆longlong。

//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI  = acos(-1.0);
const int N=70;

ULL dp
[10];
int bit
;

void pre_cal()
{
dp[0][0]=1;
for(int i=1; i<=19; i++ )   //计算不含49的
{
dp[i][0]=10*dp[i-1][0]-dp[i-1][9];
dp[i][9]=dp[i-1][0];    //以9开头
}
}

ULL cal(ULL n)  //计算区间[0~n]吉利的数量
{
int len=0, i;
ULL big=n;
while(n)
{
bit[++len]=n%10;
n/=10;
}
bit[len+1]=0;
ULL ans=0;
for(i=len ;i>0; i--)
{
ans+=dp[i-1][0]*bit[i];
if(bit[i]>4)    ans-=dp[i-1][9];
if(bit[i+1]==4&&bit[i]==9)  break;
}
if(i==0)    ans++;  //n本身是否吉利?
return big-ans+1;
}

int main()
{
//freopen("input.txt","r",stdin);
pre_cal();
int t;cin>>t;
ULL s;
while(t--)
{
scanf("%lld",&s);
printf("%llu\n",cal(s));
}
return 0;
}


AC代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: