给定一个大数 N(N 中的位数最多可达 10 5 )。任务是找到一个数字所需的切割,使得最大部分可以被 3 整除。
例子:
Input: N = 1269
Output: 3
Cut the number as 12|6|9. So, 12, 6, 9 are the
three numbers which are divisible by 3.
Input: N = 71
Output: 0
However, we make cuts there is no such number
that is divisible by 3.
方法:
让我们计算数组 res[0…n] 的值,其中 res[i] 是长度 i 的前缀的答案。显然,res[0]:=0,因为对于空字符串(长度为 0 的前缀),答案是 0。
对于 i>0,可以通过以下方式找到 res[i]:
- 让我们看一下长度为 i 的前缀的最后一位数字。它的索引为 i-1。它要么不属于可被 3 整除的段,要么属于。
- 如果不属于,则表示不能使用最后一位数字,因此res[i]=res[i-1] 。如果它属于,则找到可被 3 整除的最短s[j..i-1]并尝试使用值res[j]+1更新res[i] 。
- 一个数能被 3 整除,当且仅当它的数字之和能被 3 整除。所以任务是找到 s[0…i-1] 的最短后缀,其数字之和能被 3 整除。如果这样后缀是 s[j..i-1] 然后 s[0..j-1] 和 s[0..i-1] 具有相同的余数模 3。
- 让我们维护 remIndex[0..2]- 一个长度为 3 的数组,其中 remIndex[r] 是最长处理前缀的长度,其数字总和等于 r 模 3。使用 remIndex[r]= -1 如果没有这样的前缀。很容易看出 j=remIndex[r] 其中 r 是第 i 个前缀模 3 上的数字之和。
- 因此,要找到子串 s[j..i-1] 可被 3 整除的最大 j<=i-1,只需检查 remIndex[r] 不等于 -1 并使用 j=remIndex[r],其中 r是第 i 个前缀模 3 上的数字总和。
- 这意味着要处理最后一位数字属于可被 3 段整除的情况,请尝试使用值 res[remIndex[r]]+1 更新 res[i]。换句话说,只要执行 if (remIndex[r] != -1) => res[i] = max(res[i], res[remIndex[r]] + 1)。
下面是上述方法的实现:
C++
// CPP program to find the maximum number of
// numbers divisible by 3 in a large number
#include
using namespace std;
// Function to find the maximum number of
// numbers divisible by 3 in a large number
int MaximumNumbers(string s)
{
// store size of the string
int n = s.length();
// Stores last index of a remainder
vector remIndex(3, -1);
// last visited place of remainder
// zero is at 0.
remIndex[0] = 0;
// To store result from 0 to i
vector res(n + 1);
int r = 0;
for (int i = 1; i <= n; i++) {
// get the remainder
r = (r + s[i-1] - '0') % 3;
// Get maximum res[i] value
res[i] = res[i-1];
if (remIndex[r] != -1)
res[i] = max(res[i], res[remIndex[r]] + 1);
remIndex[r] = i+1;
}
return res[n];
}
// Driver Code
int main()
{
string s = "12345";
cout << MaximumNumbers(s);
return 0;
}
Java
// Java program to find the maximum number of
// numbers divisible by 3 in a large number
import java.util.*;
class GFG
{
// Function to find the maximum number of
// numbers divisible by 3 in a large number
static int MaximumNumbers(String s)
{
// store size of the string
int n = s.length();
// Stores last index of a remainder
int [] remIndex={-1, -1, -1};
// last visited place of remainder
// zero is at 0.
remIndex[0] = 0;
// To store result from 0 to i
int[] res = new int[n + 1];
int r = 0;
for (int i = 1; i <= n; i++)
{
// get the remainder
r = (r + s.charAt(i-1) - '0') % 3;
// Get maximum res[i] value
res[i] = res[i - 1];
if (remIndex[r] != -1)
res[i] = Math.max(res[i],
res[remIndex[r]] + 1);
remIndex[r] = i + 1;
}
return res[n];
}
// Driver Code
public static void main (String[] args)
{
String s = "12345";
System.out.println(MaximumNumbers(s));
}
}
// This code is contributed by
// chandan_jnu
Python3
# Python3 program to find the maximum
# number of numbers divisible by 3 in
# a large number
import math as mt
# Function to find the maximum number
# of numbers divisible by 3 in a
# large number
def MaximumNumbers(string):
# store size of the string
n = len(string)
# Stores last index of a remainder
remIndex = [-1 for i in range(3)]
# last visited place of remainder
# zero is at 0.
remIndex[0] = 0
# To store result from 0 to i
res = [-1 for i in range(n + 1)]
r = 0
for i in range(n + 1):
# get the remainder
r = (r + ord(string[i - 1]) -
ord('0')) % 3
# Get maximum res[i] value
res[i] = res[i - 1]
if (remIndex[r] != -1):
res[i] = max(res[i], res[remIndex[r]] + 1)
remIndex[r] = i + 1
return res[n]
# Driver Code
s= "12345"
print(MaximumNumbers(s))
# This code is contributed
# by Mohit kumar 29
C#
// C# program to find the maximum number of
// numbers divisible by 3 in a large number .
using System;
class GFG
{
// Function to find the maximum number of
// numbers divisible by 3 in a large number
static int MaximumNumbers(String s)
{
// store size of the string
int n = s.Length;
// Stores last index of a remainder
int [] remIndex = {-1, -1, -1};
// last visited place of remainder
// zero is at 0.
remIndex[0] = 0;
// To store result from 0 to i
int[] res = new int[n + 1];
int r = 0;
for (int i = 1; i <= n; i++)
{
// get the remainder
r = (r + s[i-1] - '0') % 3;
// Get maximum res[i] value
res[i] = res[i - 1];
if (remIndex[r] != -1)
res[i] = Math.Max(res[i],
res[remIndex[r]] + 1);
remIndex[r] = i + 1;
}
return res[n];
}
// Driver Code
public static void Main (String[] args)
{
String s = "12345";
Console.WriteLine(MaximumNumbers(s));
}
}
// This code has been contributed by
// PrinciRaj1992
PHP
Javascript
C++
// C++ program to find the maximum number
// of numbers divisible by 3 in large number
#include
using namespace std;
int get_max_splits(string num_string)
{
// This will contain the count of the splits
int count = 0, current_num;
// This will keep sum of all successive
// integers, when they are indivisible by 3
int running_sum = 0;
for (int i = 0; i < num_string.length(); i++)
{
current_num = num_string[i] - '0';
running_sum += current_num;
// This is the condition of finding a split
if (current_num % 3 == 0 ||
(running_sum != 0 && running_sum % 3 == 0))
{
count += 1;
running_sum = 0;
}
}
return count;
}
// Driver code
int main()
{
cout << get_max_splits("12345") << endl;
return 0;
}
// This code is contributed by Rituraj Jain
Java
// Java program to find the maximum number
// of numbers divisible by 3 in large number
class GFG
{
static int get_max_splits(String num_String)
{
// This will contain the count of the splits
int count = 0, current_num;
// This will keep sum of all successive
// integers, when they are indivisible by 3
int running_sum = 0;
for (int i = 0; i < num_String.length(); i++)
{
current_num = num_String.charAt(i) - '0';
running_sum += current_num;
// This is the condition of finding a split
if (current_num % 3 == 0 ||
(running_sum != 0 && running_sum % 3 == 0))
{
count += 1;
running_sum = 0;
}
}
return count;
}
// Driver code
public static void main(String[] args)
{
System.out.print(get_max_splits("12345") +"\n");
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to find the maximum
# number of numbers divisible by 3 in
# a large number
def get_max_splits(num_string):
# This will contain the count of the splits
count = 0
# This will keep sum of all successive
# integers, when they are indivisible by 3
running_sum = 0
for i in range(len(num_string)):
current_num = int(num_string[i])
running_sum += current_num
# This is the condition of finding a split
if current_num % 3 == 0 or (running_sum != 0 and running_sum % 3 == 0):
count += 1
running_sum = 0
return count
print get_max_splits("12345")
# This code is contributed by Amit Ranjan
C#
// C# program to find the maximum number
// of numbers divisible by 3 in large number
using System;
class GFG
{
static int get_max_splits(String num_String)
{
// This will contain the count of the splits
int count = 0, current_num;
// This will keep sum of all successive
// integers, when they are indivisible by 3
int running_sum = 0;
for (int i = 0; i < num_String.Length; i++)
{
current_num = num_String[i] - '0';
running_sum += current_num;
// This is the condition of finding a split
if (current_num % 3 == 0 ||
(running_sum != 0 && running_sum % 3 == 0))
{
count += 1;
running_sum = 0;
}
}
return count;
}
// Driver code
public static void Main(String[] args)
{
Console.Write(get_max_splits("12345") +"\n");
}
}
// This code is contributed by 29AjayKumar
PHP
Javascript
输出:
3
另一种方法:
我们可以使用 running_sum 来保存所有连续整数的总和,其中没有一个整数可以被 3 整除。 我们可以一个一个地传递每个整数并执行以下操作:
- 如果整数可被 3 整除或 running_sum 非零且可被 3 整除,则增加计数器并重置 running_sum。
- 如果整数不能被 3 整除,请跟踪所有此类连续整数的总和。
C++
// C++ program to find the maximum number
// of numbers divisible by 3 in large number
#include
using namespace std;
int get_max_splits(string num_string)
{
// This will contain the count of the splits
int count = 0, current_num;
// This will keep sum of all successive
// integers, when they are indivisible by 3
int running_sum = 0;
for (int i = 0; i < num_string.length(); i++)
{
current_num = num_string[i] - '0';
running_sum += current_num;
// This is the condition of finding a split
if (current_num % 3 == 0 ||
(running_sum != 0 && running_sum % 3 == 0))
{
count += 1;
running_sum = 0;
}
}
return count;
}
// Driver code
int main()
{
cout << get_max_splits("12345") << endl;
return 0;
}
// This code is contributed by Rituraj Jain
Java
// Java program to find the maximum number
// of numbers divisible by 3 in large number
class GFG
{
static int get_max_splits(String num_String)
{
// This will contain the count of the splits
int count = 0, current_num;
// This will keep sum of all successive
// integers, when they are indivisible by 3
int running_sum = 0;
for (int i = 0; i < num_String.length(); i++)
{
current_num = num_String.charAt(i) - '0';
running_sum += current_num;
// This is the condition of finding a split
if (current_num % 3 == 0 ||
(running_sum != 0 && running_sum % 3 == 0))
{
count += 1;
running_sum = 0;
}
}
return count;
}
// Driver code
public static void main(String[] args)
{
System.out.print(get_max_splits("12345") +"\n");
}
}
// This code is contributed by 29AjayKumar
蟒蛇3
# Python3 program to find the maximum
# number of numbers divisible by 3 in
# a large number
def get_max_splits(num_string):
# This will contain the count of the splits
count = 0
# This will keep sum of all successive
# integers, when they are indivisible by 3
running_sum = 0
for i in range(len(num_string)):
current_num = int(num_string[i])
running_sum += current_num
# This is the condition of finding a split
if current_num % 3 == 0 or (running_sum != 0 and running_sum % 3 == 0):
count += 1
running_sum = 0
return count
print get_max_splits("12345")
# This code is contributed by Amit Ranjan
C#
// C# program to find the maximum number
// of numbers divisible by 3 in large number
using System;
class GFG
{
static int get_max_splits(String num_String)
{
// This will contain the count of the splits
int count = 0, current_num;
// This will keep sum of all successive
// integers, when they are indivisible by 3
int running_sum = 0;
for (int i = 0; i < num_String.Length; i++)
{
current_num = num_String[i] - '0';
running_sum += current_num;
// This is the condition of finding a split
if (current_num % 3 == 0 ||
(running_sum != 0 && running_sum % 3 == 0))
{
count += 1;
running_sum = 0;
}
}
return count;
}
// Driver code
public static void Main(String[] args)
{
Console.Write(get_max_splits("12345") +"\n");
}
}
// This code is contributed by 29AjayKumar
PHP
Javascript
输出:
3