📌  相关文章
📜  将数字分为两个可分割的部分

📅  最后修改于: 2021-05-07 06:28:39             🧑  作者: Mango

给定一个数字(如字符串)和两个整数a和b,请将字符串分成两个非空部分,以使第一部分可被a整除,第二部分可被b整除。如果字符串不能分为两个非空部分,则输出“ NO”,否则将两个部分打印为“ YES”。

例子:

Input  : str = "123", a = 12, b = 3
Output : YES
         12, 3
"12" is divisible by a and "3" is 
divisible by b. 

Input  : str = "1200", a = 4, b = 3
Output : YES
         12, 00

Input  : str = "125", a = 12, b = 3
Output : NO

一个简单的解决方案是在所有点周围一个一个的分区阵列。对于每个分区,检查其左和右是否分别可被a和b整除。如果是,请打印左右部分,然后返回。

一种有效的解决方案是进行一些预处理,并通过从左到右扫描字符串,并通过“ b”从右到左扫描模,以“ a”保存模除。

如果我们知道从0到i的前缀的余数,除以a,则可以使用以下公式计算从0到i + 1的前缀的余数。
lr [i + 1] =(lr [i] * 10 + str [i] -‘0’)%a。

同样,可以通过从右到左扫描找到以b为模的模。我们创建另一个rl []来存储从右到左带有b的余数。

一旦我们预先计算了两个余数,就可以轻松地将分割字符串分为两部分。

C++
// C++ program to check if a string can be splitted
// into two strings such that one is divisible by 'a'
// and other is divisible by 'b'.
#include 
using namespace std;
  
// Finds if it is possible to partition str
// into two parts such that first part is
// divisible by a and second part is divisible
// by b.
void findDivision(string &str, int a, int b)
{
    int len = str.length();
  
    // Create an array of size len+1 and initialize
    // it with 0.
    // Store remainders from left to right when
    // divided by 'a'
    vector lr(len+1, 0);
    lr[0] = (str[0] - '0')%a;
    for (int i=1; i rl(len+1, 0);
    rl[len-1] = (str[len-1] - '0')%b;
    int power10 = 10;
    for (int i= len-2; i>=0; i--)
    {
        rl[i] = (rl[i+1] + (str[i]-'0')*power10)%b;
        power10 = (power10 * 10) % b;
    }
  
    // Find a point that can partition a number
    for (int i=0; i


Java
// Java program to check if a string can be splitted 
// into two strings such that one is divisible by 'a' 
// and other is divisible by 'b'. 
class GFG
{
      
// Finds if it is possible to partition str 
// into two parts such that first part is 
// divisible by a and second part is divisible 
// by b. 
static void findDivision(String str, int a, int b) 
{ 
    int len = str.length(); 
  
    // Create an array of size len+1 and initialize 
    // it with 0. 
    // Store remainders from left to right when 
    // divided by 'a' 
    int[] lr = new int[len + 1]; 
      
    lr[0] = ((int)str.charAt(0) - (int)'0')%a; 
    for (int i = 1; i < len; i++) 
        lr[i] = ((lr[i - 1] * 10) % a + 
                ((int)str.charAt(i)-(int)'0')) % a; 
  
    // Compute remainders from right to left when 
    // divided by 'b' 
    int[] rl = new int[len + 1]; 
    rl[len - 1] = ((int)str.charAt(len - 1) -
                            (int)'0') % b; 
    int power10 = 10; 
    for (int i= len - 2; i >= 0; i--) 
    { 
        rl[i] = (rl[i + 1] + ((int)str.charAt(i) - 
                        (int)'0') * power10) % b; 
        power10 = (power10 * 10) % b; 
    } 
  
    // Find a point that can partition a number 
    for (int i = 0; i < len - 1; i++) 
    { 
        // If split is not possible at this point 
        if (lr[i] != 0) 
            continue; 
  
        // We can split at i if one of the following 
        // two is true. 
        // a) All charactes after str.charAt(i] are 0 
        // b) String after str.charAt(i] is divisible by b, i.e., 
        // str.charAt(i+1..n-1] is divisible by b. 
        if (rl[i + 1] == 0) 
        { 
            System.out.println("YES"); 
            for (int k = 0; k <= i; k++) 
                System.out.print(str.charAt(k)); 
  
            System.out.print(", "); 
  
            for (int k = i + 1; k < len; k++) 
                System.out.print(str.charAt(k)); 
            return; 
        } 
    } 
    System.out.println("NO"); 
} 
  
// Driver code 
public static void main (String[] args) 
{
    String str = "123"; 
    int a = 12, b = 3; 
    findDivision(str, a, b); 
} 
}
  
// This code is contributed by mits


Python3
# Python3 program to check if a can be splitted
# into two strings such that one is divisible by 'a'
# and other is divisible by 'b'.
  
# Finds if it is possible to partition str
# into two parts such that first part is
# divisible by a and second part is divisible
# by b.
def findDivision(str, a, b):
    lenn = len(str)
      
    # Create an array of size lenn+1 and 
    # initialize it with 0.
    # Store remainders from left to right 
    # when divided by 'a'
    lr = [0] * (lenn + 1)
    lr[0] = (int(str[0]))%a
    for i in range(1, lenn):
        lr[i] = ((lr[i - 1] * 10) % a + \
                     int(str[i])) % a
                       
    # Compute remainders from right to left 
    # when divided by 'b'
    rl = [0] * (lenn + 1)
    rl[lenn - 1] = int(str[lenn - 1]) % b
    power10 = 10
    for i in range(lenn - 2, -1, -1):
        rl[i] = (rl[i + 1] + int(str[i]) * power10) % b
        power10 = (power10 * 10) % b
          
    # Find a pothat can partition a number
    for i in range(0, lenn - 1):
          
        # If split is not possible at this point
        if (lr[i] != 0):
            continue
              
        # We can split at i if one of the following
        # two is true.
        # a) All charactes after str[i] are 0
        # b) after str[i] is divisible by b, i.e.,
        # str[i+1..n-1] is divisible by b.
        if (rl[i + 1] == 0):
            print("YES")
            for k in range(0, i + 1):
                print(str[k], end = "")
              
            print(",", end = " ")
              
            for i in range(i + 1, lenn):
                print(str[k], end = "")
                return
      
    print("NO")
  
# Driver code
str = "123"
a, b = 12, 3
findDivision(str, a, b)
  
# This code is contributed by SHUBHAMSINGH10


C#
// C# program to check if a string can be splitted 
// into two strings such that one is divisible by 'a' 
// and other is divisible by 'b'. 
using System;
  
class GFG
{
      
// Finds if it is possible to partition str 
// into two parts such that first part is 
// divisible by a and second part is divisible 
// by b. 
static void findDivision(string str, int a, int b) 
{ 
    int len = str.Length; 
  
    // Create an array of size len+1 and initialize 
    // it with 0. 
    // Store remainders from left to right when 
    // divided by 'a' 
    int[] lr = new int[len + 1]; 
    lr[0] = ((int)str[0] - (int)'0')%a;
      
    for (int i = 1; i < len; i++) 
        lr[i] = ((lr[i - 1] * 10) % a + 
                ((int)str[i] - (int)'0')) % a; 
  
    // Compute remainders from right to left when 
    // divided by 'b' 
    int[] rl = new int[len + 1]; 
    rl[len - 1] = ((int)str[len - 1] - (int)'0') % b; 
      
    int power10 = 10; 
    for (int i= len - 2; i >= 0; i--) 
    { 
        rl[i] = (rl[i + 1] + ((int)str[i] - 
                (int)'0') * power10) % b; 
        power10 = (power10 * 10) % b; 
    } 
  
    // Find a point that can partition a number 
    for (int i = 0; i < len - 1; i++) 
    { 
        // If split is not possible at this point 
        if (lr[i] != 0) 
            continue; 
  
        // We can split at i if one of the following 
        // two is true. 
        // a) All charactes after str[i] are 0 
        // b) String after str[i] is divisible by b, i.e., 
        // str[i+1..n-1] is divisible by b. 
        if (rl[i + 1] == 0) 
        { 
            Console.WriteLine("YES"); 
            for (int k = 0; k <= i; k++) 
                Console.Write(str[k]); 
  
            Console.Write(", "); 
  
            for (int k = i + 1; k < len; k++) 
                Console.Write(str[k]); 
            return; 
        } 
    } 
    Console.WriteLine("NO"); 
} 
  
// Driver code 
static void Main() 
{ 
    string str = "123"; 
    int a = 12, b = 3; 
    findDivision(str, a, b); 
} 
}
  
// This code is contributed by mits


输出 :

YES
12, 3

时间复杂度: O(len)其中len是输入数字字符串的长度。