给定两个正整数N和K ,任务是计算正整数D的数量,以使D具有N个数字,并且其十进制表示形式的任何后缀都可以被K整除。
例子:
Input: N = 1, K = 2
Output: 4
Explanation:
There are 4 such integers in which any of the suffix is divisible by K:
{2, 4, 6, 8}
Input: N = 2, K = 2
Output: 45
Explanation:
There are 45, Two digit integers in which any of the suffix is divisible by 2:
Some of such integers is given below –
{10, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23…}
Notice that, 21 and 23 numbers are not divisible by 2. But their suffix 2 is divisible by 2.
天真的方法:遍历N位的所有整数,对于每个整数,检查数字的后缀是否可被K整除,如果是,则将这些数字的计数加1。
方法:想法是使用动态编程的概念,方法是增加后缀长度并将其数字从0到9重复放置。下面是步骤说明:
- 函数定义:此问题可以递归解决,在此步骤中,我们可以为N位数字的后缀选择数字。因此,递归解决方案的函数定义将是:
// Recursive Function to count of values // whose suffixes of length pos // have remainder rem with K recur(pos, rem)
- 基本情况:此问题的基本情况是,对于任何索引,带有K的后缀的其余部分变为0,然后可以将所有其他数字与所有可能的整数(从0到9)放在一起。
f(pos, 0) = 9 * (10^(n-i-1))
- 递归的情况:在递归的每一步中,我们通过将0-9之间的所有整数放入后缀长度,将后缀长度加1,然后用K更改余数,然后进行下一步。
for num in range [0-9]: f(pos, rem) += f(pos+1, (rem*10 + num)%k)
下面是上述方法的实现:
C++
// C++ implementation to Count the
// numbers with N digits and whose
// suffix is divisible by K
#include
using namespace std;
int mod = 1000000007;
int dp[1005][105][2];
int powers[1005];
int powersModk[1005];
// Suffix of length pos with
// remainder rem and Z representing
// whether the suffix has a
// non zero digit until now
int calculate(int pos, int rem,
int z, int k, int n)
{
// Base case
if (rem == 0 && z) {
// If count of digits
// is less than n
if (pos != n)
// Placing all possible
// digits in remaining
// positions
return (powers[n - pos -
1] * 9) % mod;
else
return 1;
}
// If remainder non zero
// and suffix has n digits
if (pos == n)
return 0;
// If the subproblem
// is already solved
if (dp[pos][rem][z] != -1)
return dp[pos][rem][z];
int count = 0;
// Placing all digits at MSB
// of suffix and increasing
// it's length by 1
for (int i = 0; i < 10; i++) {
if (i == 0)
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, z, k, n))) % mod;
// Non zero digit is placed
else
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, 1, k, n))) % mod;
}
// Store and return the
// solution to this subproblem
return dp[pos][rem][z] = count;
}
// Function to Count the numbers
// with N digits and whose suffix
// is divisible by K
int countNumbers(int n, int k)
{
// Since we need powers of 10
// for counting, it's better to
// pre store them along with their
// modulo with 1e9 + 7 for counting
int st = 1;
for (int i = 0; i <= n; i++) {
powers[i] = st;
st *= 10;
st %= mod;
}
// Since at each recursive step
// we increase the suffix length by 1
// by placing digits at its leftmost
// position, we need powers of 10
// modded with k, in order to fpos
// the new remainder efficiently
st = 1;
for (int i = 0; i <= n; i++) {
powersModk[i] = st;
st *= 10;
st %= mod;
}
// Initialising dp table values -1
// represents subproblem hasn't
// been solved yet
memset(dp, -1, sizeof(dp));
return calculate(0, 0, 0, k, n);
}
// Driver Code
int main()
{
int N = 2;
int K = 2;
cout << countNumbers(N, K);
return 0;
}
Java
// Java implementation to Count the
// numbers with N digits and whose
// suffix is divisible by K
import java.util.*;
import java.util.Arrays;
class GFG
{
static int mod = 1000000007;
static int dp[][][] = new int[1005][105][2];
static int powers[] = new int[1005];
static int powersModk[] = new int[1005];
// Suffix of length pos with
// remainder rem and Z representing
// whether the suffix has a
// non zero digit until now
static int calculate(int pos, int rem,
int z, int k, int n)
{
// Base case
if (rem == 0 && z!=0) {
// If count of digits
// is less than n
if (pos != n)
// Placing all possible
// digits in remaining
// positions
return (powers[n - pos -
1] * 9) % mod;
else
return 1;
}
// If remainder non zero
// and suffix has n digits
if (pos == n)
return 0;
// If the subproblem
// is already solved
if (dp[pos][rem][z] != -1)
return dp[pos][rem][z];
int count = 0;
// Placing all digits at MSB
// of suffix and increasing
// it's length by 1
for (int i = 0; i < 10; i++) {
if (i == 0)
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, z, k, n))) % mod;
// Non zero digit is placed
else
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, 1, k, n))) % mod;
}
// Store and return the
// solution to this subproblem
return dp[pos][rem][z] = count;
}
// Function to Count the numbers
// with N digits and whose suffix
// is divisible by K
static int countNumbers(int n, int k)
{
// Since we need powers of 10
// for counting, it's better to
// pre store them along with their
// modulo with 1e9 + 7 for counting
int st = 1;
int i;
for (i = 0; i <= n; i++) {
powers[i] = st;
st *= 10;
st %= mod;
}
// Since at each recursive step
// we increase the suffix length by 1
// by placing digits at its leftmost
// position, we need powers of 10
// modded with k, in order to fpos
// the new remainder efficiently
st = 1;
for (i = 0; i <= n; i++) {
powersModk[i] = st;
st *= 10;
st %= mod;
}
// Initialising dp table values -1
// represents subproblem hasn't
// been solved yet
for (int[][] row: dp)
{
for (int[] innerRow: row)
{
Arrays.fill(innerRow, -1);
}
};
return calculate(0, 0, 0, k, n);
}
// Driver Code
public static void main(String []args)
{
int N = 2;
int K = 2;
System.out.print(countNumbers(N, K));
}
}
// This code is contributed by chitranayal
Python3
# Python3 implementation to Count the
# numbers with N digits and whose
# suffix is divisible by K
mod = 1000000007
dp = [[[-1 for i in range(2)] for i in range(105)] for i in range(1005)]
powers = [0]*1005
powersModk = [0]*1005
# Suffix of length pos with
# remainder rem and Z representing
# whether the suffix has a
# non zero digit until now
def calculate(pos, rem, z, k, n):
# Base case
if (rem == 0 and z):
# If count of digits
# is less than n
if (pos != n):
# Placing all possible
# digits in remaining
# positions
return (powers[n - pos -1] * 9) % mod
else:
return 1
# If remainder non zero
# and suffix has n digits
if (pos == n):
return 0
# If the subproblem
# is already solved
if (dp[pos][rem][z] != -1):
return dp[pos][rem][z]
count = 0
# Placing all digits at MSB
# of suffix and increasing
# it's length by 1
for i in range(10):
if (i == 0):
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, z, k, n))) % mod
# Non zero digit is placed
else:
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, 1, k, n))) % mod
# Store and return the
# solution to this subproblem
dp[pos][rem][z] = count
return count
# Function to Count the numbers
# with N digits and whose suffix
# is divisible by K
def countNumbers(n, k):
# Since we need powers of 10
# for counting, it's better to
# pre store them along with their
# modulo with 1e9 + 7 for counting
st = 1
for i in range(n + 1):
powers[i] = st
st *= 10
st %= mod
# Since at each recursive step
# we increase the suffix length by 1
# by placing digits at its leftmost
# position, we need powers of 10
# modded with k, in order to fpos
# the new remainder efficiently
st = 1
for i in range(n + 1):
powersModk[i] = st
st *= 10
st %= mod
# Initialising dp table values -1
# represents subproblem hasn't
# been solved yet
# memset(dp, -1, sizeof(dp))
return calculate(0, 0, 0, k, n)
# Driver Code
if __name__ == '__main__':
N = 2
K = 2
print(countNumbers(N, K))
# This code is contributed by mohit kumar 29
C#
// C# implementation to Count the
// numbers with N digits and whose
// suffix is divisible by K
using System;
class GFG
{
static int mod = 1000000007;
static int [,,]dp = new int[1005, 105, 2];
static int []powers = new int[1005];
static int []powersModk = new int[1005];
// Suffix of length pos with
// remainder rem and Z representing
// whether the suffix has a
// non zero digit until now
static int calculate(int pos, int rem,
int z, int k, int n)
{
// Base case
if (rem == 0 && z != 0) {
// If count of digits
// is less than n
if (pos != n)
// Placing all possible
// digits in remaining
// positions
return (powers[n - pos -
1] * 9) % mod;
else
return 1;
}
// If remainder non zero
// and suffix has n digits
if (pos == n)
return 0;
// If the subproblem
// is already solved
if (dp[pos, rem, z] != -1)
return dp[pos,rem,z];
int count = 0;
// Placing all digits at MSB
// of suffix and increasing
// it's length by 1
for (int i = 0; i < 10; i++) {
if (i == 0)
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, z, k, n))) % mod;
// Non zero digit is placed
else
count = (count + (calculate(
pos + 1, (rem + (i *
powersModk[pos]) % k) %
k, 1, k, n))) % mod;
}
// Store and return the
// solution to this subproblem
return dp[pos,rem,z] = count;
}
// Function to Count the numbers
// with N digits and whose suffix
// is divisible by K
static int countNumbers(int n, int k)
{
// Since we need powers of 10
// for counting, it's better to
// pre store them along with their
// modulo with 1e9 + 7 for counting
int st = 1;
int i;
for (i = 0; i <= n; i++) {
powers[i] = st;
st *= 10;
st %= mod;
}
// Since at each recursive step
// we increase the suffix length by 1
// by placing digits at its leftmost
// position, we need powers of 10
// modded with k, in order to fpos
// the new remainder efficiently
st = 1;
for (i = 0; i <= n; i++) {
powersModk[i] = st;
st *= 10;
st %= mod;
}
// Initialising dp table values -1
// represents subproblem hasn't
// been solved yet
for(i = 0; i < 1005; i++){
for(int j = 0; j < 105; j++){
for(int l = 0; l < 2; l++)
dp[i, j, l] = -1;
}
}
return calculate(0, 0, 0, k, n);
}
// Driver Code
public static void Main(String []args)
{
int N = 2;
int K = 2;
Console.Write(countNumbers(N, K));
}
}
// This code is contributed by 29AjayKumar
45
时间复杂度: O(N * K)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。