📜  可除以3,其中每个数字是所有前缀数字模10的总和

📅  最后修改于: 2021-04-24 15:19:42             🧑  作者: Mango

给定K个数字,并以d0和d1作为两位数字来形成k个大小的整数。任务是检查使用d0和d1形成的k数是否可被3整除。
对于每个i,d i是所有前面的(更有效的)数字的和,以10为模(更正式地),以下公式必须成立:
\huge{d_{i} = \sum_{j = 0}^{i - 1}d_{j} (mod 10), 2 \leqslant i < k}
例子 :

Input : K = 5 d0 = 3 d1 = 4
Output : NO
Explanation : 
The whole number N is 34748 (Starting from 
third digit, every digit is some of preceding
digits mod 10). Since 34748 is not divisible 
by 3, answer is NO.

Input : K = 13 d0 = 8 d1 = 1
Output : YES
Explanation :
The whole number N is 8198624862486, 
which is divisible by 3, so the answer
is YES.

K可能很长,因此生成整数,计算数字总和然后检查3的倍数很麻烦。解决方案背后的关键思想是,数字在一段时间后以长度4的周期开始重复,然后可以在O(1)步骤中确定数字的总和。
我们知道d0和d1,
因此,d2 =(d0 + d1)mod 10
d3 =(d2 + d1 + d0)mod 10 =((d0 + d1)mod 10 +(d0 + d1))mod 10 = 2 *(d0 + d1)mod 10
d4 =(d3 + d2 + d1 + d0)mod 10 = 4 *(d0 + d1)mod 10
d5 =(d4 + d3 + d2 + d1 + d0)mod 10 = 8 *(d0 + d1)mod 10
d6 =(d5 + … + d1 + d0)mod 10 = 16 *(d0 + d1)mod 10 = 6 *(d0 + d1)mod 10
d7 =(d6 + … + d1 + d0)mod 10 = 32 *(d0 + d1)mod 10 = 2 *(d0 + d1)mod 10
如果继续获取di ,我们将看到结果只是遍历相同的值。我们可以看到(d0 + d1)对d2贡献1倍,对d3贡献2倍,对d4贡献4倍,对d5贡献8倍,…,对dk贡献2 ^(k – 2)倍
但是,由于2下模10从周期1,2,4,8,6,2,4。这里的权力,周期长度为4,其中d2是不存在于该循环。设S =(2 *(d0 + d1))mod 10 +(4 *(d0 + d1))mod 10 +(8 *(d0 + d1))mod 10 +(6 *(d0 + d1))mod 10,这是重复的循环。
因此,数字总和=(d0 + d1 + d2)+ S *((k – 3)/ 4)+ x 。在这里,前3个项将由d0,d1,d2覆盖,此后4个组将由S覆盖,但该公式最后仍未对某些项求和。这就是x表示残基
下面是上述方法的实现:

C++
// CPP code to check divisibility by 3
#include 
using namespace std;
 
// Function to check the divisibility
string check(long int k, int d0, int d1)
{
 
    // Cycle
    long int s = (2 * (d0 + d1)) % 10 +
                 (4 * (d0 + d1)) % 10 +
                 (8 * (d0 + d1)) % 10 +
                 (6 * (d0 + d1)) % 10;
     
    // no of residual terms
    int a = (k - 3) % 4;
     
    // sum of residual terms
    int x;
     
    switch(a)
    {
     
        // if no of residue term = 0
        case 0:
     
        x = 0;
        break;
     
        // if no of residue term = 1
        case 1:
     
        x = (2 * (d0 + d1)) % 10;
        break;
 
        // if no of residue term = 2
        case 2:
     
        x = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10;
        break;
     
        // if no of residue term = 3
        case 3:
     
        x = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10 +
            (8 * (d0 + d1)) % 10;
         
        break;
    }
     
    // sum of all digits
    long int sum = d0 + d1 + ((k - 3) / 4) * s + x;
     
    // divisibility check
    if(sum % 3 == 0)
        return "YES";
    return "NO";
}
 
// Driver code
int main()
{
 
    long int k, d0, d1;
     
    k = 13;
    d0 = 8;
    d1 = 1;
     
    cout << check(k, d0, d1) << endl;
         
    k = 5;
    d0 = 3;
    d1 = 4;
         
    cout << check(k, d0, d1) << endl;
 
    return 0;
}


Java
// Java code to check divisibility by 3
 
import java.util.*;
import java.io.*;
 
class GFG {
    // Function to check the divisibility
static String check( int k, int d0, int d1)
{
 
    // Cycle
     int s = (2 * (d0 + d1)) % 10 +
                (4 * (d0 + d1)) % 10 +
                (8 * (d0 + d1)) % 10 +
                (6 * (d0 + d1)) % 10;
     
    // no of residual terms
    int a = (k - 3) % 4;
     
    // sum of residual terms
    int x=0;
     
    switch(a)
    {
     
        // if no of residue term = 0
        case 0:
     
        x = 0;
        break;
     
        // if no of residue term = 1
        case 1:
     
        x = (2 * (d0 + d1)) % 10;
        break;
 
        // if no of residue term = 2
        case 2:
     
        x = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10;
        break;
     
        // if no of residue term = 3
        case 3:
     
        x = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10 +
            (8 * (d0 + d1)) % 10;
         
        break;
    }
     
    // sum of all digits
     int sum = d0 + d1 + (((k - 3) / 4) * s + x );
     
    // divisibility check
    if(sum % 3 == 0)
        return "YES";
    return "NO";
}
 
    //Code driven
     
    public static void main (String[] args) {
         
     int k, d0, d1;
     
    k = 13;
    d0 = 8;
    d1 = 1;
     
    System.out.println (check(k, d0, d1));
         
    k = 5;
    d0 = 3;
    d1 = 4;
         
        System.out.println (check(k, d0, d1));
         
    }
}


Python3
# Python3 code to check divisibility by 3
 
 
# Function to check the divisibility
def check(k, d0, d1):
 
    # Cycle
    s = ((2 * (d0 + d1)) % 10 +
        (4 * (d0 + d1)) % 10 +
        (8 * (d0 + d1)) % 10 +
        (6 * (d0 + d1)) % 10)
 
    # no of residual terms
    a = (k - 3) % 4
 
    # if no of residue term = 0
    if(a == 0):
        x = 0
 
    # if no of residue term = 1
    elif(a == 1):
        x = (2 * (d0 + d1)) % 10
 
    # if no of residue term = 2
    elif(a == 2):
        x = ((2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10)
 
    # if no of residue term = 3
    elif(a == 3):
        x = ((2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10 +
            (8 * (d0 + d1)) % 10)
 
    # sum of all digits
    sum = d0 + d1 + ((k - 3) // 4) * s + x
 
    # divisibility check
    if(sum % 3 == 0):
        return "YES"
    else:
        return "NO"
 
 
# Driver code
if __name__=='__main__':
    k = 13
    d0 = 8
    d1 = 1
 
    print(check(k, d0, d1))
 
    k = 5
    d0 = 3
    d1 = 4
 
    print(check(k, d0, d1))
 
# This code is contributed by
# Sanjit_Prasad


C#
// C# code to check divisibility by 3
using System;
 
class GFG
{
// Function to check the divisibility
static String check(int k, int d0, int d1)
{
 
    // Cycle
    int s = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10 +
            (8 * (d0 + d1)) % 10 +
            (6 * (d0 + d1)) % 10;
     
    // no of residual terms
    int a = (k - 3) % 4;
     
    // sum of residual terms
    int x = 0;
     
    switch(a)
    {
     
        // if no of residue term = 0
        case 0:
     
        x = 0;
        break;
     
        // if no of residue term = 1
        case 1:
     
        x = (2 * (d0 + d1)) % 10;
        break;
 
        // if no of residue term = 2
        case 2:
     
        x = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10;
        break;
     
        // if no of residue term = 3
        case 3:
     
        x = (2 * (d0 + d1)) % 10 +
            (4 * (d0 + d1)) % 10 +
            (8 * (d0 + d1)) % 10;
         
        break;
    }
     
    // sum of all digits
    int sum = d0 + d1 + (((k - 3) / 4) * s + x );
     
    // divisibility check
    if(sum % 3 == 0)
        return "YES";
    return "NO";
}
 
// Driver Code
static public void Main ()
{
     
    int k, d0, d1;
    k = 13;
    d0 = 8;
    d1 = 1;
     
    Console.WriteLine (check(k, d0, d1));
         
    k = 5;
    d0 = 3;
    d1 = 4;
         
    Console.WriteLine(check(k, d0, d1));
}
}
 
// This code is contributed by Sach_Code


PHP


Javascript


输出:
YES
NO

时间复杂度: O(1)