B-number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8313 Accepted Submission(s): 4931
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
2010 Asia Regional Chengdu Site —— Online Contest
Recommend
相比普通的数位DP,多一维来保存余数。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e3+45;
const int INF=0x3f3f3f3f;
#define charmax(x,y) x=max(x,y)
#define charmin(x,y) x=min(x,y)
#define clr(x,p) memset(x,p,sizeof x)
int n;
int s[15];int k=0;
int dp[15][15][4];
int dfs(int pos,int have,int lim,int mod_x){
int num;int mod;int hvt;
if(pos<=0){
return mod_x==0&&have==3;
}
if(!lim&&dp[pos][mod_x][have]!=-1) return dp[pos][mod_x][have];
num=lim?s[pos]:9;int ans=0;
for(int i=0;i<=num;i++){
//int ans=0;
hvt=have;
mod=(mod_x*10+i)%13;
if(hvt==0&&i==1){//have 0 number
hvt=1;
}
if(hvt==1&&i==3){// have 1 number
hvt=3;
}
if(hvt==1&&i!=1){// have b number
hvt=0;
}
ans+=dfs(pos-1,hvt,lim&&num==i,mod);
}
if(!lim) dp[pos][mod_x][have]=ans;
return ans;
}
int main()
{
while(~scanf("%d",&n)){
k=0;
clr(s,0);
while(n>0){
s[++k]=n%10;
n=n/10;
}
/*for(int i=0;i<k;i++){
swap(s[i],s[k-i-1]);
}*/
clr(dp,-1);
int ans=dfs(k,0,1,0);
printf("%d\n",ans);
}
return 0;
}