给定一个整数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序列)。在此,对于任何i,使得0≤我<⌊L/2⌋ – 1,下式成立:
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- i )d i ≤ dif ,以及满足(10 i − 10 L−1−i )d i > dif的最小值。 (直觉上,如果搜索过程中f(L, d)的“中途”值离D太远,则不可能“回来”,因此它应该“靠近” D 。)
- 因此,对于固定的L值,在O(2 ⌊L/2⌋ )时间内找到满足给定公式的N的计数。
下面是上述方法的实现:
C++
// Cpp program for the
// above approach
#include
using namespace std;
// Maximum 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 {
// Maximum 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
# Maximum 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
{
// Maximum 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.
Javascript
2
时间复杂度: O(2 L D ),其中 L D表示 D 的十进制数的位数。
辅助空间: O( L D )