HDU3652
Description
A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
Output
Print each answer in a single line.
Sample Input
13 100 200 1000
Sample Output
1 1 2 2
题意
给定一个n,求1-n之间的所有B数(含有13且能被13整除的数)的个数
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#define LL long long int
using namespace std;
LL num[25];
int dp[20][20][3];//dp[i][j][k]表示在第i位且面临的余数为j,状态为k时的结果
//k = 0 表示结尾不是1, k = 1表示结尾是1,k = 2表示含有13
LL pow10[25];
void init(){
pow10[0] = 1;
for(int i = 1;i <= 19;i++){
pow10[i] = pow10[i-1] * 10;
}
}
int toArr(LL x){
int pos = 0;
while(x){
num[pos] = x % 10;
x = x / 10;
pos++;
}
return pos;
}
LL DFS(int pos,int mod,int state,bool flag){
if(pos < 0){
return 0;
}
//cout<<pos<<" "<<mod<<" "<<state<<endl;
LL ans = 0;
int maxV = flag?num[pos]:9;
if(!flag && dp[pos][mod][state] != -1){
return dp[pos][mod][state];
}
if(pos == 0){
if(state == 0){
return 0;
}
else if(state == 1){
if((mod+3)%13 == 0 && maxV >= 3){
return 1;
}
else{
return 0;
}
}
else{
for(int i = 0;i <= maxV;i++){
LL nexMod = (mod + i) % 13;
if(nexMod == 0){
ans++;
}
}
return ans;
}
}
for(int i = 0;i <= maxV;i++){
LL nexMod = (mod + (i * pow10[pos]) % 13) % 13;
//cout<<"mod: "<<mod<<" "<<i * pow10[pos]<<" "<<nexMod<<endl;
if(state == 0){
if(i == 1){
ans += DFS(pos - 1,nexMod,1,flag&&i==maxV);
}
else{
ans += DFS(pos - 1,nexMod,0,flag&&i==maxV);
}
}
else if(state == 1){
if(i == 3){
ans += DFS(pos - 1,nexMod,2,flag&&i==maxV);
}
else if(i != 1){
ans += DFS(pos - 1,nexMod,0,flag&&i==maxV);
}
else{
ans += DFS(pos - 1,nexMod,1,flag&&i==maxV);
}
}
else{
ans += DFS(pos - 1,nexMod,2,flag&&i==maxV);
}
}
if(!flag){
dp[pos][mod][state] = ans;
}
return ans;
}
int main()
{
LL n;
init();
memset(dp,-1,sizeof(dp));
while(scanf("%lld",&n)!=EOF){
int digit = toArr(n);
LL ans = DFS(digit - 1,0,0,true);
printf("%lld\n",ans);
}
return 0;
}