标签:
Description
Input
Output
Sample Input
13 100 200 1000
Sample Output
1 1 2 2
求出1到n中含有13 且能被13整除的数的个数。
dp1[i][j][k]代表不含13的 i位的 以j开头的 且对13取余 的数的个数
dp2[i][j][k]代表包含13的 i位的 以j开头的 且对13取余 的数的个数
对于边界情况,要判断是不是包含了13 且能不能被13整除,当条件满足时才能被累加。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define LL __int64 LL dp1[12][12][13] , dp2[12][12][13] ;//dp1 i位最高位j 余数为k 不含13 int digit[12] , cnt ; LL f(int n,int j) { LL i , k = j ; for(i = 0 ; i < n ; i++) k *= 10 ; return k ; } void init() { int i , j , k , l , temp ; memset(dp1,0,sizeof(dp1)) ; memset(dp2,0,sizeof(dp2)) ; for(j = 0 ; j < 10 ; j++) dp1[1][j][ j%13 ] = 1 ; for(i = 2 ; i <= 10 ; i++) { for(j = 0 ; j < 10 ; j++) { temp = f(i-1,j) ; for(k = 0 ; k < 10 ; k++) { for(l = 0 ; l < 13 ; l++) { dp2[i][j][ (temp+l)%13 ] += dp2[i-1][k][l] ; if( j == 1 && k == 3 ) dp2[i][j][ (temp+l)%13 ] += dp1[i-1][k][l] ; else dp1[i][j][ (temp+l)%13 ] += dp1[i-1][k][l] ; } } } } return ; } LL solve(LL temp) { memset(digit,0,sizeof(digit)) ; cnt = 0 ; while( temp ) { digit[++cnt] = temp%10 ; temp /= 10 ; } LL ans = 0 , i , j , flag = 0 , k ; for(j = 0 ; j < digit[cnt] ; j++) ans += dp2[cnt][j][0] ; temp = f(cnt-1,digit[cnt]) ; for(i = cnt-1 ; i > 0 ; i--) { for(j = 0 ; j < digit[i] ; j++) { for(k = 0 ; k < 13 ; k++) { if( (temp+k)%13 == 0 ) ans += dp2[i][j][k] ; if( (temp+k)%13 == 0 && ( digit[i+1] == 1&& j == 3) ) ans += dp1[i][j][k] ; else if( (temp+k)%13 == 0 && flag ) ans += dp1[i][j][k] ; } } if( digit[i+1] == 1 && digit[i] == 3 ) flag = 1 ; temp = temp + f(i-1,digit[i]) ; } return ans ; } int main() { LL n ; init() ; int i , j , k ; while( scanf("%I64d", &n) != EOF ) { printf("%I64d\n", solve(n+1) ) ; } return 0; }
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42914787