给定一个整数D ,任务是找到所有可能的正整数N的计数,以使reverse(N) = N + D。
例子:
Input: D = 63
Output: 2
Explanation:
For N = 18, 18 + 63 = 81, which satisfies the condition N + D = reverse(N).
For N = 29, 29 + 63 = 92, which satisfies the condition N + D = reverse(N).
Therefore, the required output is 2
Input: D = 75
Output: 0
方法:可以根据以下观察结果解决问题:
N + D = reverse(N) => N – reverse(N) = D
=> D = ∑(i=0 to [L/2]-1)(10L-1-i -10i )*( ni – nL-1-i), L = Count of digits in N.
If di = ni − nL−1−i (0 ≤ i ≤ ⌊L/2⌋ − 1)
reverse(N) − N = ∑(i=0 to [L/2]-1) (10L-1-i -10i )*di
请按照以下步骤解决问题:
- 令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 ,以下成立:
10L−1−i − 10i > ∑(j=i+1 to [L/2 – 1]) ((10L−1−j − 10j) · 9) + 10L−⌊L/2⌋
- 令L D为D的十进制数。然后,当L> 2L D且f(L,d)> 0时,可以看出f(L,d)> D。
- 因此,它足以考虑大号d和2L 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 )