Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 12675 Accepted Submission(s): 4525
Problem Description
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
Input
The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.
The input terminates by end of file marker.
The input terminates by end of file marker.
Output
For each test case, output an integer indicating the final points of the power.
3
1
50
500
Sample Output
0
1
15
Author
fatboy_cw@WHU
题目大意:
给你一个数据n,让你求出(0-n]之间包含49的数据个数。
思路:求不包含49的数据个数,然后再用n-这个个数即可,处理方法:数位dp、
我们设dp【i】【j】表示长度为i的,第i位上数据为j的个数,然后一点一点一点一点一点一点慢慢加起来。
预处理dp【i】【j】:
void init()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=21;i++)//枚举长度
{
for(int j=0;j<10;j++)//枚举第i位上的数据
{
for(int k=0;k<10;k++)//枚举第i-1位上的数据。
{
if(!(j==4&&k==9))//合法的情况下累加
{
dp[i][j]+=dp[i-1][k];//长度为i,数据为j的情况数。
}
}
}
}
}
AC代码:
这里因为solve()函数求的是(0-n)的数据,所以在处理的时候n要+1,因为long long 的数据是到2^63-1的,所以我们避免2^63会出现不对的数据,我们开llu。
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll unsigned long long
ll dp[25][10];
ll digit[25];
void init()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=21;i++)
{
for(int j=0;j<10;j++)
{
for(int k=0;k<10;k++)
{
if(!(j==4&&k==9))
{
dp[i][j]+=dp[i-1][k];//长度为i,最后数字为j的情况数。
}
}
}
}
}
ll calchangdu(ll n)
{
ll cont=0;
while(n)
{
cont++;
n/=10;
}
return cont;
}
ll caldigit(ll n,ll len)
{
memset(digit,0,sizeof(digit));
for(int i=1;i<=len;i++)
{
digit[i]=n%10;
n/=10;
}
}
ll solve(ll n)
{
ll ans=0;
ll len=calchangdu(n);//计算出n的长度
caldigit(n,len);//计算出n的每一位数据
for(int i=len;i>=1;i--)
{
for(int j=0;j<digit[i];j++)
{
if(!(digit[i+1]==4&&j==9))
{
ans+=dp[i][j];
}
}
if(digit[i]==9&&digit[i+1]==4)break;
}
return ans;
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
ll n;
scanf("%I64u",&n);
printf("%I64u\n",(n+1)-solve(n+1));
}
}