思路按照训练指南上说的的递推,table[i][j][k]表示i位数各位数字和对给定数取模为j,数字本身对给定数取模为k的数字个数,最后的统计细节需要注意,要从高位到低位统计,个位要单算。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::make_pair; using std::greater; using std::endl; const int MAXN(82); int table[11][MAXN+10][MAXN+10]; int arr[11][MAXN+10][MAXN+10]; int count(int sour, int K) { if(sour < 10) return sour/K; int weight = 1, mxb = 0; while(sour/weight >= 10) { weight *= 10; ++mxb; } int b1 = 0, b2 = 0; int ret = 0; for(int i = mxb; i > 0; --i) { int temp = sour/weight; for(int j = 0; j < temp; ++j) ret += table[i-1][((K-j-b1)%K+K)%K][((K-j*weight-b2)%K+K)%K]; b1 += temp; b2 += temp*weight; sour -= temp*weight; weight /= 10; } for(int i = 0; i <= sour; ++i) if(((K-i-b1)%K+K)%K == 0 && ((K-i-b2)%K+K)%K == 0) ++ret; --ret; return ret; } int main() { int T; scanf("%d", &T); while(T--) { int A, B, K; scanf("%d%d%d", &A, &B, &K); if(K > MAXN) { printf("0\n"); continue; } memset(table, 0, sizeof(table)); int size = -1, tb = B;; while(tb) { ++size; tb /= 10; } for(int i = 0; i <= 9; ++i) table[0][i%K][i%K] += 1; int weight = 1; for(int i = 1; i < size; ++i) { weight *= 10; for(int k1 = 0; k1 < K; ++k1) for(int k2 = 0; k2 < K; ++k2) for(int j = 0; j <= 9; ++j) table[i][(k1+j)%K][((j*weight+k2)%K+K)%K] += table[i-1][k1][k2]; } printf("%d\n", count(B, K)-count(A-1, K)); } return 0; }
LL count(LL sour, LL goal, LL BASE) //原数, 数字k, 进制 { if(sour < 0) return 0LL; LL weight = 1LL, ts = 0LL; LL ret = 0LL; while(sour) { LL t1 = sour%BASE, t2 = sour/BASE; if(t1 > goal) ++t2; else if(t1 == goal) ret += (ts+1); ret += weight*t2; if(!goal) ret -= weight; ts += t1*weight; sour /= BASE; weight *= BASE; } if(!goal) ++ret; return ret; }