B-number
Problem 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
Author
wqb0039
Source
Recommend
lcy
题目大意:
给定一个数n,问你 1~n 有多少个数本身既是13的倍数,且数位中含有13
解题思路:
很明显是数位DP,用 长度,是否包含13,前一个数位,以及对13求余后的余数 这四维来表示DP的状态。
解题代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
using namespace std;
int dp[11][2][15][15];
const int w[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
string st;
int DP(int len,int f,int pre,int left){
if(len==0){
if(f==1 && left==0 ) return 1;
else return 0;
}
if(dp[len][f][pre][left]!=-1) return dp[len][f][pre][left];
int ans=0;
for(int i=0;i<=9;i++){
if(i==3 && pre==1 ) ans+=DP(len-1,1,i,(left+w[len-1]*i)%13 );
else ans+=DP(len-1,f,i,(left+w[len-1]*i)%13 );
}
return dp[len][f][pre][left]=ans;
}
int dfs(int len,int f,int pre,int left){
if(len<=0){
if(f==1 && left==0 ) return 1;
else return 0;
}
int x=st[st.length()-len]-'0';
int ans=0;
for(int i=0;i<x;i++){
if(pre==1 && i==3) ans+=DP(len-1,1,i,( left+ i*w[len-1])%13 );
else ans+=DP(len-1,f,i,( left+ i*w[len-1])%13 );
}
if(pre==1 && x==3) ans+=dfs(len-1,1,x, ( left+ x*w[len-1])%13 );
else ans+=dfs(len-1,f,x, ( left+ x*w[len-1])%13 );
return ans;
}
int main(){
int n;
memset(dp,-1,sizeof(dp));
while(cin>>n){
stringstream ss;
ss<<n;
ss>>st;
cout<<dfs(st.length(),0,0,0)<<endl;
}
return 0;
}