YBT431 B数计数

题目描述

我们称十进制形式包含子字符串 13 ,并且可以被 整除的数为B数。例如, 和 就是B数,而 和 不是。您的任务是计算 到 之间的B数个数。

输入格式

有多组数据,每组数据仅有一个正整数 。 数据以 EOF 结束。

输出格式

对于每一组数据,输出一个非负数,表示 到 之间的B数个数。

样例

输入样例

13
100
200
1000

输出样例

1
1
2
2


第一次写数位dp, 极其暴力,留个代码

\(f_{i, j, k, l}\)表示从高到低枚举到第i位时, 状态为j(j==0表示啥都没有, 1表示只有1,2表示存在13),(k=0表示不可以*放置,k=1表示可以放0-9任意一个数), l表示对13取模的值。、

上 代 码!!!!

#include <iostream> 
#include <cstdio>
using namespace std;

const int N = 12;
int n = 10;
int number[N];
int f[N][3][2][13];
int pow[N];

int read(){
	int num=0; char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) num=num*10+c-‘0‘, c=getchar();
	return num;
} 

void solve(){
	
	for(int i=0; i<=n; i++){
		for(int j=0; j<=2; j++){
			for(int k=0; k<13; k++)
			f[i][j][0][k] = f[i][j][1][k] = 0;
		}
	}
	
	int flag = 0;
	
	
	for(int i=0; i<=n; i++){
		if(number[i] == 0 && flag==0){
			f[i][0][0][0] = 1;
			flag = 1;
			continue;
		} 
		
		for(int k=0; k<13; k++)
		for(int j=0; j<=9; j++){
			
			int m = (j*pow[i])%13;
			int need = (k-m+13)%13;
			
			if(j < number[i]){
				f[i][2][1][k] += f[i-1][2][1][need] + f[i-1][2][0][need];
				if(j == 1){
					f[i][1][1][k] += f[i-1][1][0][need] + f[i-1][1][1][need] + f[i-1][0][1][need] + f[i-1][0][0][need];
				}else if(j == 3){
					f[i][2][1][k] += f[i-1][1][0][need] + f[i-1][1][1][need];
					
					f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][0][0][need];
				}else{
					f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][0][0][need] + f[i-1][1][1][need] + f[i-1][1][0][need];
				}
			}else if(j == number[i]){
				f[i][2][1][k] += f[i-1][2][1][need];
				f[i][2][0][k] += f[i-1][2][0][need];
				if(j == 1){
					f[i][1][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
					f[i][1][0][k] += f[i-1][1][0][need] + f[i-1][0][0][need];
				}else if(j == 3){
					f[i][2][1][k] += f[i-1][1][1][need];
					f[i][2][0][k] += f[i-1][1][0][need];
					
					f[i][0][1][k] += f[i-1][0][1][need];
					f[i][0][0][k] += f[i-1][0][0][need];
				}else{
					f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
					f[i][0][0][k] += f[i-1][0][0][need] + f[i-1][1][0][need];
				}
			}else if(j > number[i]){
				f[i][2][1][k] += f[i-1][2][1][need];
				if(j == 1){
					f[i][1][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
				}else if(j == 3){
					f[i][2][1][k] += f[i-1][1][1][need];
					f[i][0][1][k] += f[i-1][0][1][need];
				}else{
					f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
				}
			}
		}
	}
	
	
	cout << f[n][2][0][0] + f[n][2][1][0] << endl;
}

int main(){
	int x;
	while(cin >> x){
		for(int i=0; i<=n; i++) number[i] = 0;
		int l = 1;
		for(int i=n; i>=0; i--){
			number[i] = x%10;
			pow[i] = l;
			l *= 10;
			x /= 10; 
		}
		solve();
	}
	return 0;
}

YBT431 B数计数

上一篇:401. 二进制手表


下一篇:VS2010 代码下面出现红色波浪线 处理办法