📜  具有与D相等的倒数的差的整数计数

📅  最后修改于: 2021-04-29 03:17:18             🧑  作者: Mango

给定一个整数D ,任务是找到所有可能的正整数N的计数,以使reverse(N) = N + D。

例子:

方法:可以根据以下观察结果解决问题:

请按照以下步骤解决问题:

  • f(L,D)= reverse(N)-N 。找到满足给定公式的N的计数几乎等同于枚举L对和范围为[−9,9]{d 0 ,d 1 ,…的整数序列。 。 , d⌊L/2⌋-1 } (尽管考虑到有多个N对应于d i的序列)。在此,对于0≤i <⌊L/2⌋− 1的任何i ,以下成立:
  • L DD的十进制数。然后,当L> 2L Df(L,d)> 0时,可以看出f(L,d)> D。
  • 因此,它足以考虑大号d2L d之间的值作为L的值。
  • 对于L的固定值,请考虑枚举序列{d 0 ,d 1 ,…, d⌊L/ 2⌋−1 } ,使得f(L,d)= D (并找到满足给定N的个数)公式),通过从d 0开始执行深度优先搜索。
  • 当已经确定到d i-1的值时,可以看出,最多要考虑两个d i值的候选:最大值,使得(10 i -10 L-1- ⅰ)D≤DIF,最小值,使得(10 I – 10 L-1-i)的D> DIF。 (直觉上,如果搜索过程中f(L,d)的“中途”值距离D太远,则不可能“退回”,因此应“保持”接近D。 )
  • 因此,对于固定的L值,在O( 2⌊L/2⌋ )时间中找到满足给定公式的N的计数。

下面是上述方法的实现:

C++
// Cpp program for the
// above approach
#include 
 
using namespace std;
 
// Maxium digits in N
int MAXL = 17;
int N;
vector v;
 
// Function to find count
// of possible values
// of N such that N + D = reverse(N)
int count(int D, int l, int t, int x[])
{
 
    // Base Case
    if (t == N) {
 
        // If D is not qual to 0
        if (D != 0)
            return 0;
 
        // Stores count of possible values
        // of N such that N + D = reverse(N)
        long ans = 1;
 
        for (int i = 0; i < N; i++) {
 
            // Update ans
            ans *= (i == 0 ? 9 : 10) - abs(x[i]);
        }
 
        // If l is even
        if (l % 2 == 0) {
 
            // Update ans
            ans *= 10;
        }
 
        return ans;
    }
 
    // Stores count of possible values
    // of N such that N + D = reverse(N)
    long ans = 0;
 
    // Iterae over the range [-9, 9]
    for (int m = -9; m <= 9; m++) {
 
        if (-v[t] < D + v[t] * m && D +
                      v[t] * m < v[t]) {
 
            x[t] = m;
 
            // Update ans
            ans += count(D + v[t] * m, l,
                                 t + 1, x);
        }
    }
 
    return ans;
}
 
// Utility function to find count of N
// such that N + D = reverse(N)
int findN(int D)
{
 
    // If d is a multiple of 9,
    // no such value N found
    if (D % 9 != 0)
        return 0;
 
    // Divide D by 9 check reverse
    // of number and its sum
    D /= 9;
 
    // B[i]: Stores power of (10, i)
    vector B(MAXL);
    B[0] = 1;
 
    // Calculate power(10, i)
    for (int i = 1; i < MAXL; i++) {
 
        // Update B[i]
        B[i] = B[i - 1] * 10;
    }
 
    // Stores count of N such
    // that N + D = reverse(N)
    int ans = 0;
 
    // Iterate over the range [1, MAXL]
    for (int i = 1; i <= MAXL; i++) {
 
        N = (i + 1) / 2;
        v.clear();
        v.resize(N);
        for (int j = 0; j < N; j++)
            for (int k = j; k < i - j; k++)
                v[j] += B[k];
 
        int arr[N];
        ans += count(D, i, 0, arr);
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int D = 63;
 
    // Function call
    cout << findN(D);
}


Java
// Java program of the above approach
import java.util.*;
 
public class Main {
 
    // Maxium digits in N
    static final int MAXL = 17;
    static int N;
    static long[] v;
 
    // Utility function to find count of N
    // such that N + D = reverse(N)
    static long findN(int D)
    {
 
        // If d is a multiple of 9,
        // no such value N found
        if (D % 9 != 0)
            return 0;
 
        // Divide D by 9 check reverse
        // of number and its sum
        D /= 9;
 
        // B[i]: Stores power of (10, i)
        long[] B = new long[MAXL];
        B[0] = 1;
 
        // Calculate power(10, i)
        for (int i = 1; i < MAXL; i++) {
 
            // Update B[i]
            B[i] = B[i - 1] * 10;
        }
 
        // Stores count of N such
        // that N + D = reverse(N)
        long ans = 0;
 
        // Iterate over the range [1, MAXL]
        for (int i = 1; i <= MAXL; i++) {
 
            N = (i + 1) / 2;
            v = new long[N];
            for (int j = 0; j < N; j++)
                for (int k = j; k < i - j; k++)
                    v[j] += B[k];
 
            // Update ans
            ans += count(D, i, 0, new int[N]);
        }
 
        return ans;
    }
 
    // Function to find count of possible values
    // of N such that N + D = reverse(N)
    static long count(long D, int l,
                      int t, int[] x)
    {
 
        // Base Case
        if (t == N) {
 
            // If D is not qual to 0
            if (D != 0)
                return 0;
 
            // Stores count of possible values
            // of N such that N + D = reverse(N)
            long ans = 1;
 
            for (int i = 0; i < N; i++) {
 
                // Update ans
                ans *= (i == 0 ? 9 : 10)
                       - Math.abs(x[i]);
            }
 
            // If l is even
            if (l % 2 == 0) {
 
                // Update ans
                ans *= 10;
            }
 
            return ans;
        }
 
        // Stores count of possible values
        // of N such that N + D = reverse(N)
        long ans = 0;
 
        // Iterae over the range [-9, 9]
        for (int m = -9; m <= 9; m++) {
 
            if (-v[t] < D + v[t] * m
                && D + v[t] * m < v[t]) {
 
                x[t] = m;
 
                // Update ans
                ans += count(D + v[t] * m,
                             l, t + 1, x);
            }
        }
 
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int D = 63;
 
        // Function call
        System.out.println(findN(D));
 
        sc.close();
    }
}


Python3
# Python program of the above approach
 
# Maxium digits in N
MAXL = 17;
N = 0;
v = 0;
 
# Utility function to find count of N
# such that N + D = reverse(N)
def findN(D):
    global N;
    global v;
     
    # If d is a multiple of 9,
    # no such value N found
    if (D % 9 != 0):
        return 0;
 
    # Divide D by 9 check reverse
    # of number and its sum
    D //= 9;
 
    # B[i]: Stores power of (10, i)
    B = [0]*MAXL;
    B[0] = 1;
 
    # Calculate power(10, i)
    for i in range(1, MAXL):
       
        # Update B[i]
        B[i] = B[i - 1] * 10;
 
    # Stores count of N such
    # that N + D = reverse(N)
    ans = 0;
 
    # Iterate over the range [1, MAXL]
    for i in range(1, MAXL + 1):
        N = (i + 1) // 2;
        v = [0]*N;
        for j in range(N):
            for k in range(j, i - j):
                v[j] += B[k];
 
        # Update ans
        temp = [0]*N;
        ans += count(D, i, 0, temp);
        return ans;
 
# Function to find count of possible values
# of N such that N + D = reverse(N)
def count(D, l, t, x):
    global N;
    global v;
     
    # Base Case
    if (t == N):
 
        # If D is not qual to 0
        if (D != 0):
            return 0;
 
        # Stores count of possible values
        # of N such that N + D = reverse(N)
        ans = 1;
        for i in range(N):
           
            # Update ans
            ans *= (9 if i == 0 else 10) - abs(x[i]);
 
        # If l is even
        if (l % 2 == 0):
           
            # Update ans
            ans *= 10;
        return ans;
 
    # Stores count of possible values
    # of N such that N + D = reverse(N)
    ans = 0;
 
    # Iterae over the range [-9, 9]
    for m in range(-9, 10):
        if (-v[t] < D + v[t] * m and D + v[t] * m < v[t]):
            x[t] = m;
 
            # Update ans
            ans += count(D + v[t] * m, l, t + 1, x);
    return ans;
 
# Driver Code
if __name__ == '__main__':
    D = 63;
 
    # Function call
    print(findN(D));
 
    # This code is contributed by 29AjayKumar


C#
// C# program for the above approach
using System;
class GFG
{
   
    // Maxium digits in N
    static int MAXL = 17;
    static int N;
    static long[] v;
 
    // Utility function to find count of N
    // such that N + D = reverse(N)
    static long findN(int D)
    {
 
        // If d is a multiple of 9,
        // no such value N found
        if (D % 9 != 0)
            return 0;
 
        // Divide D by 9 check reverse
        // of number and its sum
        D /= 9;
 
        // B[i]: Stores power of (10, i)
        long[] B = new long[MAXL];
        B[0] = 1;
 
        // Calculate power(10, i)
        for (int i = 1; i < MAXL; i++)
        {
 
            // Update B[i]
            B[i] = B[i - 1] * 10;
        }
 
        // Stores count of N such
        // that N + D = reverse(N)
        long ans = 0;
 
        // Iterate over the range [1, MAXL]
        for (int i = 1; i <= MAXL; i++)
        {
            N = (i + 1) / 2;
            v = new long[N];
            for (int j = 0; j < N; j++)
                for (int k = j; k < i - j; k++)
                    v[j] += B[k];
 
            // Update ans
            ans += count(D, i, 0, new int[N]);
        }
        return ans;
    }
 
    // Function to find count of possible values
    // of N such that N + D = reverse(N)
    static long count(long D, int l,
                      int t, int[] x)
    {
 
        // Base Case
        if (t == N)
        {
 
            // If D is not qual to 0
            if (D != 0)
                return 0;
 
            // Stores count of possible values
            // of N such that N + D = reverse(N)
            long ans = 1;
            for (int i = 0; i < N; i++)
            {
 
                // Update ans
                ans *= (i == 0 ? 9 : 10)
                       - Math.Abs(x[i]);
            }
 
            // If l is even
            if (l % 2 == 0)
            {
 
                // Update ans
                ans *= 10;
            }
            return ans;
        }
 
        // Stores count of possible values
        // of N such that N + D = reverse(N)
        long anss = 0;
 
        // Iterae over the range [-9, 9]
        for (int m = -9; m <= 9; m++)
        {
            if (-v[t] < D + v[t] * m
                && D + v[t] * m < v[t])
            {
                x[t] = m;
 
                // Update ans
                anss += count(D + v[t] * m,
                             l, t + 1, x);
            }
        }
        return anss;
    }
  
  // Driver code
  public static void Main(String[] args)
  {
        int D = 63;
 
        // Function call
        Console.WriteLine(findN(D));
  }
}
 
// This code is contributed by code_hunt.


输出:
2

时间复杂度: O(2 L D ),其中L D表示D的十进制数字。
辅助空间: O(L D )