考虑一个非常长的K位数N,其位数为d 0 ,d 1 ,…,d K-1 (用十进制表示; d 0是最高有效位,d K-1最低有效位)。这个数字太大,以至于不能明确给出或写下来。而是仅给出其起始数字,并提供一种构造数字其余部分的方法。
具体来说,给定d 0和d 1 ;对于每个i≥2,d i是所有前面的(更有效的)数字的总和,取模10,形式更正式–
确定N是否为3的倍数。
Constraints:
2 ≤K ≤1012
1 ≤d0 ≤9
0 ≤d1 ≤9
例子:
Input : K = 13, d0 = 8, d1 = 1
Output : YES
说明:整数N是8198624862486 ,可以被3整除,
所以答案是肯定的。
Input : K = 5, d0 = 3, d1 = 4
Output : NO
说明:整数N为34748 ,不能被3整除,
所以答案是否定的。
方法1(蛮力)
我们可以使用蛮力法,通过使用给定的迭代构造数字的条件(先前数字的和为10)来计算整数N,并检查数字是否可被3整除。但是,由于位数(K)可以多达10 12 ,因此我们不能将其存储为整数,因为它会比’long long int’的最大范围大得多。因此,以下是确定N是否为3的倍数的有效方法。
方法2(高效)
解决方案背后的关键思想是以下事实:在一段长度为4的周期中,数字在一段时间后开始重复。首先,我们将找到所有数字的总和,然后确定该数字是否可以被3整除或不被3整除。
We know d0 and d1.
d2 = ( d0 + d1 ) % 10
d3 = ( d2 + d1 + d0 ) % 10 = (( d0 + d1) % 10 + d0 + d1) % 10 = 2 * ( d0 + d1 ) % 10
Similarly,
d4 = ( d3 + d2 + d1 + d0 ) % 10 = 4 * ( d0 + d1 ) % 10
d5 = ( d4 + d3 + d2 + d1 + d0 ) % 10 = 8 * ( d0 + d1 ) % 10
d6 = ( d5 + … + d1 + d0 ) % 10 = 16 * (d0 + d3) % 10 = 6 * ( d0 + d1 ) % 10
d7 = ( d6 + … + d1 + d0 ) % 10 = 12 * ( d0 + d1 ) % 10 = 2 * ( d0 + d1 ) % 10
如果继续寻找d i ,我们将看到结果只是围绕相同的值(2、4、8、6)循环。
在此,周期长度为4,而d 2在周期中不存在。因此,在d 2之后,循环开始从(2,4,8,8)中的任何值开始以4的长度形成,但以相同的顺序给出连续四位数字的和= S = 2 + 4 + 8 + 6 = 20 。因此,整数的总和为= d 0 + d 1 + d 2 + S *(k – 3)/ 4 + x,其中前三个项将由d 0 ,d 1 ,d 2覆盖
然后,这4个组将被S覆盖。但是,由于(k – 3)可能不是4的倍数,因此将剩下一些剩余的数字,这些数字将被x覆盖,可以通过运行循环来计算这些数字,条款将少于4。
例如,当K = 13时
数字总和= d 0 + d 1 + d 2 + S *(13 – 3)/ 4 + x = d 0 + d 1 + d 2 + S * 2 + x,
其中第一个S将具有d 3 ,d 4 ,d 5 ,d 6和第二个S将具有d 7 ,d 8 ,d 9 ,d 10和
x = d 11 + d 12
- d 11 = 2 *(d 0 + d 1 )%10
- d 12 = 4 *(d 0 + d 1 )%10
下面是上述想法的实现:
C++
// CPP Program to determine if
// number N of given form is
// divisible by 3 or not
#include
using namespace std;
// function returns true if number N is
// divisible by 3 otherwise false,
// dig0 - most significant digit
// dig1 - 2nd most significant digit
// K - number of digits
bool multipleOfThree(int K, int dig0, int dig1)
{
// sum of digits
long long int sum = 0;
// store the sum of first two digits
// modulo 10 in a temporary variable
int temp = (dig0 + dig1) % 10;
sum = dig0 + dig1;
// if the number N is a two digit number
if (K == 2) {
if (sum % 3 == 0)
return true;
else
return false;
}
// add temp to sum to get the sum
// of first three digits which are
// not a part of cycle
sum += temp;
// get the number of groups in cycle
long long int numberofGroups = (K - 3) / 4;
// get the remaining number of digits
int remNumberofDigits = (K - 3) % 4;
// if temp = 5 or temp = 0 then sum of each group will
// be 0
if (temp == 5 || temp == 0)
sum += (numberofGroups * 0);
else
// add sum of 20 for each group (2, 4, 8, 6)
sum += (numberofGroups * 20);
// find the remaining sum of remaining digits
for (int i = 0; i < remNumberofDigits; i++) {
temp = (2 * temp) % 10;
sum += temp;
}
// check if it is divisible by 3 or not
if (sum % 3 == 0)
return true;
else
return false;
}
// Driver Code
int main()
{
int K = 5, dig0 = 3, dig1 = 4;
if (multipleOfThree(K, dig0, dig1))
cout << "YES" << endl;
else
cout << "NO" << endl;
K = 10;
dig0 = 3;
dig1 = 2;
if (multipleOfThree(K, dig0, dig1))
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}
Java
// Java Program to determine if
// number N of given form is
// divisible by 3 or not
import java.io.*;
public class GFG {
// function returns true if number N is
// divisible by 3 otherwise false,
// dig0 - most significant digit
// dig1 - 2nd most significant digit
// K - number of digits
static boolean multipleOfThree(int K, int dig0,
int dig1)
{
// sum of digits
long sum = 0;
// store the sum of first two digits
// modulo 10 in a temporary variable
int temp = (dig0 + dig1) % 10;
sum = dig0 + dig1;
// if the number N is a two digit number
if (K == 2) {
if (sum % 3 == 0)
return true;
else
return false;
}
// add temp to sum to get the sum
// of first three digits which are
// not a part of cycle
sum += temp;
// get the number of groups in cycle
long numberofGroups = (K - 3) / 4;
// get the remaining number of digits
int remNumberofDigits = (K - 3) % 4;
// add sum of 20 for each group (2, 4, 8, 6)
sum += (numberofGroups * 20);
// find the remaining sum of
// remaining digits
for (int i = 0; i < remNumberofDigits; i++) {
temp = (2 * temp) % 10;
sum += temp;
}
// check if it is divisible by 3 or not
if (sum % 3 == 0)
return true;
else
return false;
}
// Driver Code
static public void main(String[] args)
{
int K = 5, dig0 = 3, dig1 = 4;
if (multipleOfThree(K, dig0, dig1))
System.out.println("Yes");
else
System.out.println("No");
}
}
// This code is contributed by vt_m.
Python 3
# Python 3 Program to determine if
# number N of given form is
# divisible by 3 or not
# function returns true if number N
# is divisible by 3 otherwise false,
# dig0 - most significant digit
# dig1 - 2nd most significant digit
# K - number of digits
def multipleOfThree(K, dig0, dig1):
# sum of digits
sum = 0
# store the sum of first two digits
# modulo 10 in a temporary variable
temp = (dig0 + dig1) % 10
sum = dig0 + dig1
# if the number N is a
# two digit number
if (K == 2):
if (sum % 3 == 0):
return True
else:
return False
# add temp to sum to get the sum
# of first three digits which are
# not a part of cycle
sum += temp
# get the number of groups in cycle
numberofGroups = (K - 3) // 4
# get the remaining number of digits
remNumberofDigits = (K - 3) % 4
# add sum of 20 for each
# group (2, 4, 8, 6)
sum += (numberofGroups * 20)
# find the remaining sum of
# remaining digits
for i in range(remNumberofDigits):
temp = (2 * temp) % 10
sum += temp
# check if it is divisible
# by 3 or not
if (sum % 3 == 0):
return True
else:
return False
# Driver Code
if __name__ == "__main__":
K = 5
dig0 = 3
dig1 = 4
if (multipleOfThree(K, dig0, dig1)):
print("Yes")
else:
print("No")
# This code is contributed by ChitraNayal
C#
// C# Program to determine if
// number N of given form is
// divisible by 3 or not
using System;
class GFG {
// function returns true if number N is
// divisible by 3 otherwise false,
// dig0 - most significant digit
// dig1 - 2nd most significant digit
// K - number of digits
static bool multipleOfThree(int K, int dig0, int dig1)
{
// sum of digits
long sum = 0;
// store the sum of first two digits
// modulo 10 in a temporary variable
int temp = (dig0 + dig1) % 10;
sum = dig0 + dig1;
// if the number N is
// a two digit number
if (K == 2) {
if (sum % 3 == 0)
return true;
else
return false;
}
// add temp to sum to get the sum
// of first three digits which are
// not a part of cycle
sum += temp;
// get the number of groups in cycle
long numberofGroups = (K - 3) / 4;
// get the remaining number of digits
int remNumberofDigits = (K - 3) % 4;
// add sum of 20 for each group (2, 4, 8, 6)
sum += (numberofGroups * 20);
// find the remaining sum of
// remaining digits
for (int i = 0; i < remNumberofDigits; i++) {
temp = (2 * temp) % 10;
sum += temp;
}
// check if it is divisible by 3 or not
if (sum % 3 == 0)
return true;
else
return false;
}
// Driver Code
static public void Main(String[] args)
{
int K = 5, dig0 = 3, dig1 = 4;
if (multipleOfThree(K, dig0, dig1))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed by vt_m.
PHP
Javascript
NO
NO
时间复杂度: O(1)
辅助空间: O(1)