Number of substrings divisible by 8 and not by 3 in C++

C++Server Side ProgrammingProgramming

A string of 0-9 is given. For this problem, we need to calculate the number of strings that are divisible by 8 and not by 3. This is a 2 step problem, and we need to do the code one step at a time to solve it, for example

Input

str = "80"

Output

2

Input

str = "7675636788"

Output

15

Approach to Find the Solution

Only numbers with their last 3 digits are divisible by 8, and their sum of digits divisible by 3 are divisible by 8.

Now store the prefix sum of the string so that the sum of digits of prefix module 3 is either 0,1, or 2. Then the string is iterated for all the positions of i. Then count the number of substrings at i, which are divisible by 8—now, subtracting the number of substrings at i, which are divisible by 3 from this value.

|S| X 3 size 2D array is defined, |S| is the size of a string, say dp[i][j].

At any index i dp[i][j]. Starting from index i to 0, the number of substrings have the output j. So 0<=j<=0, since module 3.

We need to iterate over the string to check if one-digit, two-digit, and three-digit numbers are divisible by 8.

  • To determine if a character is 8 at index, check the number at index.

  • Divide the number by 8 rather than 3 if there are two digits.

Let us assume the number is divisible by 8. There must be two (1-3) substrings if it is divisible by 8. However, it will also have the substrings, which are divisible by 8. To remove them.

Example

#include <bits/stdc++.h>
using namespace std;

#define MAX 1000
int count (char s[], int len) {
   int cur = 0,
   dig = 0;
   int sum[MAX], dp[MAX][3];
   memset (sum, 0, sizeof (sum));
   memset (dp, 0, sizeof (dp));
   dp[0][0] = 1;
   for (int i = 1; i <= len; i++) {
      dig = int (s[i - 1]) - 48;
      cur += dig;
      cur %= 3;
      sum[i] = cur;
      dp[i][0] = dp[i - 1][0];
      dp[i][1] = dp[i - 1][1];
      dp[i][2] = dp[i - 1][2];
      dp[i][sum[i]]++;
   }
   int ans = 0, dprev = 0, value = 0, dprev2 = 0;
   for (int i = 1; i <= len; i++) {
      dig = int (s[i - 1]) - 48;
      if (dig == 8) ans++;
      if (i - 2 >= 0) {
         dprev = int (s[i - 2]) - 48;
         value = dprev * 10 + dig;
         if ((value % 8 == 0) && (value % 3 != 0)) ans++;
      }
      // Taking 3 digit number.
      if (i - 3 >= 0){
         dprev2 = int (s[i - 3]) - 48;
         dprev = int (s[i - 2]) - 48;
         value = dprev2 * 100 + dprev * 10 + dig;
         if (value % 8 != 0) continue;
            ans += (i - 2);
         ans -= (dp[i - 3][sum[i]]);
      }
   }
   return ans;
}
int main () {
   char str[] = "7675636788";
   int len = strlen (str);
   cout << count (str, len) << endl;
   return 0;
}

Output

4

Conclusion

In this problem, we learned how to find the number of substrings divisible by 8 and not by 3 along with the c++ code. This code can also be written in java, python, and other languages. To solve this problem, we have reversed a string to find the number of substrings divisible by 8 but not divisible by 3. It is a very straightforward problem once we divide it into 2 parts.

raja
Updated on 07-Mar-2022 06:52:37

Advertisements