📜  长度为N的数字A和B,且数字的总和仅包含数字A和B

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

给定三个正整数NAB。任务是计算仅包含数字A和B且其数字总和也仅包含数字A和B的长度N的数量。以10 9 + 7的模数打印答案。

例子:

方法:这个想法是将数字的总和表示为线性方程式,包含两个变量,即
S = X * A + Y * B其中AB是给定的数字, XY分别是这些数字的频率。
由于(X + Y)的总和根据给定条件应等于N (数字的长度),因此我们可以将Y替换为(N – X) ,等式简化为S = X * A +(N – X)* B。因此,X =(S – N * B)/(A – B)。
现在,我们可以遍历S的所有可能的值,其中S的最小值为N位的数字,其中所有数字是1和S的最大值是N位的数字,其中所有数字都是9,检查如果当前值包含仅数字AB。使用上述公式为有效电流SXY的值。既然如此,我们还可以将当前值S的数字位数替换为(N!/ X!Y!) 。将此结果添加到最终答案中。
注意:使用费马小定理来计算n! %p

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
const int MAX = 1e5 + 5;
const int MOD = 1e9 + 7;
#define ll long long
  
// Function that returns true if the num contains
// a and b digits only
int check(int num, int a, int b)
{
    while (num) {
        int rem = num % 10;
        num /= 10;
        if (rem != a && rem != b)
            return 0;
    }
    return 1;
}
  
// Modular Exponentiation
ll power(ll x, ll y)
{
    ll ans = 1;
    while (y) {
        if (y & 1)
            ans = (ans * x) % MOD;
        y >>= 1;
        x = (x * x) % MOD;
    }
    return ans % MOD;
}
  
// Function to return the modular inverse
// of x modulo MOD
int modInverse(int x)
{
    return power(x, MOD - 2);
}
  
// Function to return the required count
// of numbers
ll countNumbers(int n, int a, int b)
{
    ll fact[MAX], inv[MAX];
    ll ans = 0;
  
    // Generating factorials of all numbers
    fact[0] = 1;
    for (int i = 1; i < MAX; i++) {
        fact[i] = (1LL * fact[i - 1] * i);
        fact[i] %= MOD;
    }
  
    // Generating inverse of factorials modulo
    // MOD of all numbers
    inv[MAX - 1] = modInverse(fact[MAX - 1]);
    for (int i = MAX - 2; i >= 0; i--) {
        inv[i] = (inv[i + 1] * (i + 1));
        inv[i] %= MOD;
    }
  
    // Keeping a as largest number
    if (a < b)
        swap(a, b);
  
    // Iterate over all possible values of s and
    // if it is a valid S then proceed further
    for (int s = n; s <= 9 * n; s++) {
        if (!check(s, a, b))
            continue;
  
        // Check for invalid cases in the equation
        if (s < n * b || (s - n * b) % (a - b) != 0)
            continue;
        int numDig = (s - n * b) / (a - b);
        if (numDig > n)
            continue;
  
        // Find answer using combinatorics
        ll curr = fact[n];
        curr = (curr * inv[numDig]) % MOD;
        curr = (curr * inv[n - numDig]) % MOD;
  
        // Add this result to final answer
        ans = (ans + curr) % MOD;
    }
    return ans;
}
  
// Driver Code
int main()
{
    int n = 3, a = 1, b = 3;
    cout << countNumbers(n, a, b);
  
    return 0;
}


Java
// Java implementation of the approach
  
class GFG
{
      
static int MAX = (int)(1E5 + 5);
static long MOD = (long)(1E9 + 7);
  
// Function that returns true if the num contains
// a and b digits only
static boolean check(long num, long a, long b)
{
    while (num > 0) 
    {
        long rem = num % 10;
        num /= 10;
        if (rem != a && rem != b)
            return false;
    }
    return true;
}
  
// Modular Exponentiation
static long power(long x, long y)
{
    long ans = 1;
    while (y > 0) 
    {
        if ((y & 1) > 0)
            ans = (ans * x) % MOD;
        y >>= 1;
        x = (x * x) % MOD;
    }
    return ans % MOD;
}
  
// Function to return the modular inverse
// of x modulo MOD
static long modInverse(long x)
{
    return power(x, MOD - 2);
}
  
// Function to return the required count
// of numbers
static long countNumbers(long n, long a, long b)
{ 
    long[] fact = new long[MAX];
    long[] inv = new long[MAX];
    long ans = 0;
  
    // Generating factorials of all numbers
    fact[0] = 1;
    for (int i = 1; i < MAX; i++)
    {
        fact[i] = (1 * fact[i - 1] * i);
        fact[i] %= MOD;
    }
  
    // Generating inverse of factorials modulo
    // MOD of all numbers
    inv[MAX - 1] = modInverse(fact[MAX - 1]);
    for (int i = MAX - 2; i >= 0; i--)
    {
        inv[i] = (inv[i + 1] * (i + 1));
        inv[i] %= MOD;
    }
  
    // Keeping a as largest number
    if (a < b)
    {
        long x = a;
        a = b;
        b = x;
    }
  
    // Iterate over all possible values of s and
    // if it is a valid S then proceed further
    for (long s = n; s <= 9 * n; s++)
    {
        if (!check(s, a, b))
            continue;
  
        // Check for invalid cases in the equation
        if (s < n * b || (s - n * b) % (a - b) != 0)
            continue;
        int numDig = (int)((s - n * b) / (a - b));
        if (numDig > n)
            continue;
  
        // Find answer using combinatorics
        long curr = fact[(int)n];
        curr = (curr * inv[numDig]) % MOD;
        curr = (curr * inv[(int)n - numDig]) % MOD;
  
        // Add this result to final answer
        ans = (ans + curr) % MOD;
    }
    return ans;
}
  
// Driver Code
public static void main (String[] args) 
{
    long n = 3, a = 1, b = 3;
    System.out.println(countNumbers(n, a, b));
}
}
  
// This code is contributed by mits


Python3
# Python 3 implementation of the approach
MAX = 100005;
MOD = 1000000007
  
# Function that returns true if the num 
# contains a and b digits only
def check(num, a, b):
    while (num):
        rem = num % 10
        num = int(num / 10)
        if (rem != a and rem != b):
            return 0
      
    return 1
  
# Modular Exponentiation
def power(x, y):
    ans = 1
    while (y):
        if (y & 1):
            ans = (ans * x) % MOD
        y >>= 1
        x = (x * x) % MOD
  
    return ans % MOD
  
# Function to return the modular 
# inverse of x modulo MOD
def modInverse(x):
    return power(x, MOD - 2)
  
# Function to return the required 
# count of numbers
def countNumbers(n, a, b):
    fact = [0 for i in range(MAX)]
    inv = [0 for i in range(MAX)]
    ans = 0
  
    # Generating factorials of all numbers
    fact[0] = 1
    for i in range(1, MAX, 1):
        fact[i] = (1 * fact[i - 1] * i)
        fact[i] %= MOD
  
    # Generating inverse of factorials 
    # modulo MOD of all numbers
    inv[MAX - 1] = modInverse(fact[MAX - 1])
    i = MAX - 2
    while(i >= 0):
        inv[i] = (inv[i + 1] * (i + 1))
        inv[i] %= MOD
        i -= 1
  
    # Keeping a as largest number
    if (a < b):
        temp = a
        a = b
        b = temp
  
    # Iterate over all possible values of s and
    # if it is a valid S then proceed further
    for s in range(n, 9 * n + 1, 1):
        if (check(s, a, b) == 0):
            continue
  
        # Check for invalid cases in the equation
        if (s < n * b or (s - n * b) % (a - b) != 0):
            continue
        numDig = int((s - n * b) / (a - b))
        if (numDig > n):
            continue
  
        # Find answer using combinatorics
        curr = fact[n]
        curr = (curr * inv[numDig]) % MOD
        curr = (curr * inv[n - numDig]) % MOD
  
        # Add this result to final answer
        ans = (ans + curr) % MOD
  
    return ans
  
# Driver Code
if __name__ == '__main__':
    n = 3
    a = 1
    b = 3
    print(countNumbers(n, a, b))
  
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the approach
using System;
  
class GFG
{
      
static long MAX = (long)(1E5 + 5);
static long MOD = (long)(1E9 + 7);
  
// Function that returns true if the num contains
// a and b digits only
static bool check(long num, long a, long b)
{
    while (num > 0) 
    {
        long rem = num % 10;
        num /= 10;
        if (rem != a && rem != b)
            return false;
    }
    return true;
}
  
// Modular Exponentiation
static long power(long x, long y)
{
    long ans = 1;
    while (y > 0) 
    {
        if ((y & 1) > 0)
            ans = (ans * x) % MOD;
        y >>= 1;
        x = (x * x) % MOD;
    }
    return ans % MOD;
}
  
// Function to return the modular inverse
// of x modulo MOD
static long modInverse(long x)
{
    return power(x, MOD - 2);
}
  
// Function to return the required count
// of numbers
static long countNumbers(long n, long a, long b)
{ 
    long[] fact = new long[MAX];
    long[] inv = new long[MAX];
    long ans = 0;
  
    // Generating factorials of all numbers
    fact[0] = 1;
    for (long i = 1; i < MAX; i++)
    {
        fact[i] = (1 * fact[i - 1] * i);
        fact[i] %= MOD;
    }
  
    // Generating inverse of factorials modulo
    // MOD of all numbers
    inv[MAX - 1] = modInverse(fact[MAX - 1]);
    for (long i = MAX - 2; i >= 0; i--)
    {
        inv[i] = (inv[i + 1] * (i + 1));
        inv[i] %= MOD;
    }
  
    // Keeping a as largest number
    if (a < b)
    {
        long x = a;
        a = b;
        b = x;
    }
  
    // Iterate over all possible values of s and
    // if it is a valid S then proceed further
    for (long s = n; s <= 9 * n; s++)
    {
        if (!check(s, a, b))
            continue;
  
        // Check for invalid cases in the equation
        if (s < n * b || (s - n * b) % (a - b) != 0)
            continue;
        long numDig = (s - n * b) / (a - b);
        if (numDig > n)
            continue;
  
        // Find answer using combinatorics
        long curr = fact[n];
        curr = (curr * inv[numDig]) % MOD;
        curr = (curr * inv[n - numDig]) % MOD;
  
        // Add this result to final answer
        ans = (ans + curr) % MOD;
    }
    return ans;
}
  
// Driver Code
static void Main()
{
    long n = 3, a = 1, b = 3;
    Console.WriteLine(countNumbers(n, a, b));
}
}
  
// This code is contributed by mits


输出:
1