c++ - Count numbers in range divisible by K with a sum of digits in range -


i have such task:

let's call number "lucky" if divisible k , sum of digits lays in [p, q]. count quantity of "lucky" numbers in [a, b].

1 ≤ a, b < 10^11,
1 ≤ p, q ≤ 99,
1 ≤ k ≤ 10^11.

time each test - 5 seconds

here code

#include <iostream> #include <fstream> using namespace std;  int sum; long long k; int number[10]; int digits[10]; int p; int q; long long a; long long b; int delta; bool flag = false; long long memory[100000][100][10][2];  long long pow (int a, int b) {     long long res = 1;     for(int = 0; < b; i++)         res *= a;     return res; } int sumofdigits(long long number) {     int sum = 0;     while(number != 0)     {         sum += number % 10;         number /= 10;     }     return sum; } long long tolong(int digits[], int n) {     long long sum = 0;     for(int = 0; < n; i++)     {         sum *= 10;         sum += digits[i];     }     return sum; } long long function(long long remainder// remainder of division k,                       int currsum // current sum of digits,                        int n //number of digit added,                        bool alldigitsallowed //says if digits can added number) {     if(n == 10)     {         int counter = 0;         for(int = p; <= q; i++)         {              long long res = - currsum + remainder;             if(res%k == 0 && (alldigitsallowed || i-currsum <= number[9]))             {                 counter++;                 if(!alldigitsallowed && number[9] == i-currsum)                     flag = true;             }         }         return counter;     }     long long res = 0;     int temp = 0;     while(currsum + temp <= q)     {            long long tempremainder = (temp*pow(10,10-n)+remainder)%k;         if(temp == number[n-1] && !alldigitsallowed)         {             if(tempremainder < 100000)             {                 if(memory[tempremainder][currsum+temp][n+1][false] == -1)                     memory[tempremainder][currsum+temp][n+1][false] = function(tempremainder, currsum + temp, n+1,false);                 res += memory[tempremainder][currsum+temp][n+1][false];             }             else                 res += function(tempremainder, currsum + temp, n+1,false);             //res += function(tempremainder, currsum + temp, n+1,false);             break;         }         else         {             if(tempremainder < 100000)             {                 if(memory[tempremainder][currsum+temp][n+1][true] == -1)                     memory[tempremainder][currsum+temp][n+1][true] = function(tempremainder, currsum + temp, n+1,true);                 res += memory[tempremainder][currsum+temp][n+1][true];             }             else                 res += function(tempremainder, currsum + temp, n+1,true);         }         temp++;     }     return res; }  long long f (long long a) {     flag = false;     memset(&number, 0, sizeof(number));     sum = 0;     int = 9;     while(a != 0)     {         number[i] = a%10;         /= 10;         i--;     }     for(int j = 0; j < 10; j++)         swap(number[j],number[9-j]);     return function(0,0,1,false); }  int main() {     ifstream in("lucky.in");     ofstream out("lucky.out");     in >> k >> p >> q >> >> b;     sum = p;     memset(&memory, -1, sizeof(memory));     long long result = - f(a) + flag;     memset(&memory, -1, sizeof(memory));     out<< result + f(b) << endl;     return 0; } 

in solution try make number determined sum of digits, adding digits 1 one. problem can't memorize the remainders of division k.

so how can deal problem?

i use like:

unsigned int compute_number_sum(uint64_t n) {     unsigned int res = 0;      while (n != 0) {         const uint64_t nd = n / 10;         res += static_cast<unsigned int>(n - 10 * nd); // equivalent res += n % 10         n = nd;     }     return res; }  uint64_t count_lucky_number(uint64_t a, uint64_t b, uint64_t k,                              unsigned int p, unsigned int q) {     uint64_t res = 0;     const uint64_t min_i = (a + k - 1) / k * k;     (uint64_t = min_i; <= b; += k) {         const unsigned int numbersum = compute_number_sum(i);         res += p <= numbersum && numbersum <= q;     }     return res; } 

Comments

Popular posts from this blog

PHPMotion implementation - URL based videos (Hosted on separate location) -

javascript - Using Windows Media Player as video fallback for video tag -

c# - Unity IoC Lifetime per HttpRequest for UserStore -