给定字符串数字“ 0-9”。任务是找到可以被8整除但不能被3整除的子字符串数。
例子 :
Input : str = "888"
Output : 5
Substring indexes : (1, 1), (1, 2), (2, 2),
(2, 3), (3, 3).
Input : str = "6564525600"
Output : 15
如果数字的总和可被3整除,则该数字可被3整除;如果最后三位可被8整除,则该数字可被8整除。
现在,我们的想法是存储字符串的前缀总和,即前缀的数量,以使前缀模3的数字总和为0、1、2。接下来,我们遍历字符串,并对每个位置i计数以i结尾并且可以被8整除的子字符串数。从该值中,我们减去以i结尾并且可以被3整除的子字符串数。
我们定义一个| S | X 3大小的2D数组,| S |是字符串的大小,例如dp [i] [j]。
可以将dp [i] [j]定义为任意索引i,从索引0到索引i的子字符串数具有输出j
当将索引0的数字加到索引i并取模3时。因此,0 <= j <= 2,因为模3。
现在,我们将遍历字符串并检查每个可被8整除的一位数字,两位数字和三位数字。
对于一位数字,只需检查索引处的字符是否为8。
对于两位数,请检查它是否可被8整除而不能被3整除。
对于三位数,请形成数字并检查数字是否可以被8整除。如果数字是可整除的,则最后三位数字必须可被8整除。因此,所有以该索引结尾的子串都可被8整除,即(i-3)子串。
但是它也将包含那些可以被3整除的子字符串,因此只需使用dp [i] [j]删除它们即可。
C/C++
// CPP Program to count substrings which are
// divisible by 8 but not by 3
#include
using namespace std;
#define MAX 1000
// Returns count of substrings divisible by 8
// but not by 3.
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;
// Iterating the string.
for (int i = 1; i <= len; i++)
{
dig = int(s[i-1])-48;
cur += dig;
cur %= 3;
sum[i] = cur;
// Prefix sum of number of substrings whose
// sum of digits mudolo 3 is 0, 1, 2.
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;
// Iterating the string.
for (int i = 1; i <= len; i++)
{
dig = int(s[i-1])-48;
// Since single digit 8 is divisible
// by 8 and not by 3.
if (dig == 8)
ans++;
// Taking two digit number.
if (i-2 >= 0)
{
dprev = int(s[i-2])-48; // 10th position
value = dprev*10 + dig; // Complete 2 digit
// number
if ((value%8 == 0) && (value%3 != 0))
ans++;
}
// Taking 3 digit number.
if (i-3 >= 0)
{
dprev2 = int(s[i-3])-48; // 100th position
dprev = int(s[i-2])-48; // 10th position
// Complete 3 digit number.
value = dprev2*100 + dprev*10 + dig;
if (value%8 != 0)
continue;
// If number formed is divisible by 8 then
// last 3 digits are also divisible by 8.
// Then all the substring ending at this
// index is divisible.
ans += (i-2);
// But those substring also contain number
// which are not divisible by 3 so
// remove them.
ans -= (dp[i-3][sum[i]]);
}
}
return ans;
}
// Driven Program
int main()
{
char str[] = "6564525600";
int len = strlen(str);
cout << count(str, len) <
Java
// Java program to count substrings which are
// divisible by 8 but not by 3
import java.io.*;
class GFG
{
// Function that returns count of substrings divisible by 8
// but not by 3
static int count(String s, int len)
{
int MAX = 1000;
int cur = 0, dig = 0;
int[] sum = new int[MAX];
int[][] dp = new int[MAX][3];
dp[0][0] = 1;
// Iterating the string.
for (int i = 1; i <= len; i++)
{
dig = (int)(s.charAt(i-1)) - 48;
cur += dig;
cur %= 3;
sum[i] = cur;
// Prefix sum of number of substrings whose
// sum of digits mudolo 3 is 0, 1, 2.
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;
// Iterating the string.
for (int i = 1; i <= len; i++)
{
dig = (int)(s.charAt(i-1)) - 48;
// Since single digit 8 is divisible
// by 8 and not by 3.
if (dig == 8)
ans++;
// Taking two digit number.
if (i-2 >= 0)
{
dprev = (int)(s.charAt(i-2)) - 48; // 10th position
value = dprev*10 + dig; // Complete 2 digit
// number
if ((value%8 == 0) && (value%3 != 0))
ans++;
}
// Taking 3 digit number.
if (i-3 >= 0)
{
dprev2 = (int)(s.charAt(i-3)) - 48; // 100th position
dprev = (int)(s.charAt(i-2)) - 48; // 10th position
// Complete 3 digit number.
value = dprev2*100 + dprev*10 + dig;
if (value%8 != 0)
continue;
// If number formed is divisible by 8 then
// last 3 digits are also divisible by 8.
// Then all the substring ending at this
// index is divisible.
ans += (i-2);
// But those substring also contain number
// which are not divisible by 3 so
// remove them.
ans -= (dp[i-3][sum[i]]);
}
}
return ans;
}
// driver program
public static void main (String[] args)
{
String str = "6564525600";
int len = str.length();
System.out.println(count(str, len));
}
}
// Contributed by Pramod Kumar
Python3
# Python3 Program to count substrings
# which are divisible by 8 but not by 3
# Returns count of substrings
# divisible by 8 but not by 3.
def count(s, Len):
global MAX
cur = 0
dig = 0
Sum = [0] * MAX
dp = [[0, 0, 0] for i in range(MAX)]
dp[0][0] = 1
# Iterating the string.
for i in range(1, Len + 1):
dig = int(s[i - 1]) - 48
cur += dig
cur %= 3
Sum[i] = cur
# Prefix sum of number of substrings
# whose sum of digits mudolo 3 is
# 0, 1, 2.
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]] += 1
ans = 0
dprev = 0
value = 0
dprev2 = 0
# Iterating the string.
for i in range(1, Len + 1):
dig = int(s[i - 1]) - 48
# Since single digit 8 is
# divisible by 8 and not by 3.
if dig == 8:
ans += 1
# Taking two digit number.
if i - 2 >= 0:
dprev = int(s[i - 2]) - 48 # 10th position
value = dprev * 10 + dig # Complete 2 digit
# number
if (value % 8 == 0) and (value % 3 != 0):
ans += 1
# Taking 3 digit number.
if i - 3 >= 0:
dprev2 = int(s[i - 3]) - 48 # 100th position
dprev = int(s[i - 2]) - 48 # 10th position
# Complete 3 digit number.
value = (dprev2 * 100 +
dprev * 10 + dig)
if value % 8 != 0:
continue
# If number formed is divisible by 8
# then last 3 digits are also divisible
# by 8. Then all the substring ending
# at this index are divisible.
ans += (i - 2)
# But those substring also contain
# number which are not divisible
# by 3 so remove them.
ans -= (dp[i - 3][Sum[i]])
return ans
# Driver Code
MAX = 1000
Str = "6564525600"
Len = len(Str)
print(count(Str, Len))
# This code is contributed
# by PranchalK
C#
// C# program to count substrings which are
// divisible by 8 but not by 3
using System;
class GFG
{
// Function that returns count of substrings
// divisible by 8 but not by 3
static int count(String s, int len)
{
int MAX = 1000;
int cur = 0, dig = 0;
int[] sum = new int[MAX];
int[,] dp = new int[MAX,3];
dp[0, 0] = 1;
// Iterating the string.
for (int i = 1; i <= len; i++)
{
dig = (int)(s[i-1]) - 48;
cur += dig;
cur %= 3;
sum[i] = cur;
// Prefix sum of number of substrings whose
// sum of digits mudolo 3 is 0, 1, 2.
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;
// Iterating the string.
for (int i = 1; i <= len; i++)
{
dig = (int)(s[i-1]) - 48;
// Since single digit 8 is divisible
// by 8 and not by 3.
if (dig == 8)
ans++;
// Taking two digit number.
if (i-2 >= 0)
{
dprev = (int)(s[i-2]) - 48; // 10th position
value = dprev*10 + dig; // Complete 2 digit number
if ((value % 8 == 0) && (value % 3 != 0))
ans++;
}
// Taking 3 digit number.
if (i - 3 >= 0)
{
dprev2 = (int)(s[i-3]) - 48; // 100th position
dprev = (int)(s[i-2]) - 48; // 10th position
// Complete 3 digit number.
value = dprev2 * 100 + dprev * 10 + dig;
if (value % 8 != 0)
continue;
// If number formed is divisible by 8 then
// last 3 digits are also divisible by 8.
// Then all the substring ending at this
// index is divisible.
ans += (i - 2);
// But those substring also contain number
// which are not divisible by 3 so
// remove them.
ans -= (dp[i - 3,sum[i]]);
}
}
return ans;
}
// driver program
public static void Main (String[] args)
{
String str = "6564525600";
int len = str.Length;
Console.Write(count(str, len));
}
}
// This code is contributed by parashar.
输出:
15