给定字符串数字“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 大小的二维数组,|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
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。