📌  相关文章
📜  可能的数字截断,以使最大部分可被3整除

📅  最后修改于: 2021-04-22 09:18:47             🧑  作者: Mango

给定一个大数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 [i]的值更新为res [j] +1
  • 当且仅当数字的总和能被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


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


输出:
3

另一种方法:
我们可以使用running_sum来保留所有连续整数的和,其中单个整数都不能被3整除。我们可以将每个整数一一传递并执行以下操作:

  1. 如果整数可被3整除或running_sum不为零且可被3整除,则增加计数器并重置running_sum。
  2. 如果整数不能被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

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


输出:
3