给定一个数n,我们需要计算n位数字的总数,使得偶数位之和比奇数位之和多1。这里偶数和奇数表示数字的位置类似于数组索引,例如,最左边(或前导)的数字被认为是偶数,最左边的第二位被认为是奇数等等。
例子:
Input: n = 2
Output: Required Count of 2 digit numbers is 9
Explanation : 10, 21, 32, 43, 54, 65, 76, 87, 98.
Input: n = 3
Output: Required Count of 3 digit numbers is 54
Explanation: 100, 111, 122, ......, 980
我们强烈建议您将浏览器最小化,然后自己先尝试一下。
这个问题主要是对n位数字之和等于给定和的数的扩展。这里子问题的解取决于四个变量:digits、esum(当前偶数和)、osum(当前奇数和)、isEven(指示当前数字是偶数还是奇数的标志)。
下面是基于 Memoization 的解决方案。
C++
// A memoization based recursive program to count numbers
// with difference between odd and even digit sums as 1
#include
using namespace std;
// A lookup table used for memoization.
unsigned long long int lookup[50][1000][1000][2];
// Memnoization based recursive function to count numbers
// with even and odd digit sum difference as 1. This function
// considers leading zero as a digit
unsigned long long int countRec(int digits, int esum,
int osum, bool isOdd, int n)
{
// Base Case
if (digits == n)
return (esum - osum == 1);
// If current subproblem is already computed
if (lookup[digits][esum][osum][isOdd] != -1)
return lookup[digits][esum][osum][isOdd];
// Initialize result
unsigned long long int ans = 0;
// If the current digit is odd, then add it to odd sum and recur
if (isOdd)
for (int i = 0; i <= 9; i++)
ans += countRec(digits+1, esum, osum+i, false, n);
else // Add to even sum and recur
for (int i = 0; i <= 9; i++)
ans += countRec(digits+1, esum+i, osum, true, n);
// Store current result in lookup table and return the same
return lookup[digits][esum][osum][isOdd] = ans;
}
// This is mainly a wrapper over countRec. It
// explicitly handles leading digit and calls
// countRec() for remaining digits.
unsigned long long int finalCount(int n)
{
// Initialize number digits considered so far
int digits = 0;
// Initialize all entries of lookup table
memset(lookup, -1, sizeof lookup);
// Initializa final answer
unsigned long long int ans = 0;
// Initialize even and odd sums
int esum = 0, osum = 0;
// Explicitly handle first digit and call recursive function
// countRec for remaining digits. Note that the first digit
// is considered as even digit.
for (int i = 1; i <= 9; i++)
ans += countRec(digits+1, esum + i, osum, true, n);
return ans;
}
// Driver program
int main()
{
int n = 3;
cout << "Coutn of "<
Java
// A memoization based recursive
// program to count numbers with
// difference between odd and
// even digit sums as 1
class GFG
{
// A lookup table used for memoization.
static int [][][][]lookup = new int[50][1000][1000][2];
// Memnoization based recursive
// function to count numbers
// with even and odd digit sum
// difference as 1. This function
// conisders leading zero as a digit
static int countRec(int digits, int esum,
int osum, int isOdd, int n)
{
// Base Case
if (digits == n)
return (esum - osum == 1)?1:0;
// If current subproblem is already computed
if (lookup[digits][esum][osum][isOdd] != -1)
return lookup[digits][esum][osum][isOdd];
// Initialize result
int ans = 0;
// If current digit is odd, then
// add it to odd sum and recur
if (isOdd==1)
for (int i = 0; i <= 9; i++)
ans += countRec(digits+1, esum, osum+i, 0, n);
else // Add to even sum and recur
for (int i = 0; i <= 9; i++)
ans += countRec(digits+1, esum+i, osum, 1, n);
// Store current result in lookup
// table and return the same
return lookup[digits][esum][osum][isOdd] = ans;
}
// This is mainly a wrapper over countRec. It
// explicitly handles leading digit and calls
// countRec() for remaining digits.
static int finalCount(int n)
{
// Initialize number digits considered so far
int digits = 0;
// Initialize all entries of lookup table
for(int i = 0; i < 50; i++)
for(int j = 0; j < 1000; j++)
for(int k = 0; k < 1000; k++)
for(int l = 0; l < 2; l++)
lookup[i][j][k][l] = -1;
// Initializa final answer
int ans = 0;
// Initialize even and odd sums
int esum = 0, osum = 0;
// Explicitly handle first digit and
// call recursive function countRec
// for remaining digits. Note that
// the first digit is considered
// as even digit.
for (int i = 1; i <= 9; i++)
ans += countRec(digits+1, esum + i, osum, 1, n);
return ans;
}
// Driver program
public static void main(String[] args)
{
int n = 3;
System.out.println("Coutn of "+ n +
" digit numbers is " + finalCount(n));
}
}
// This code has been contributed by 29AjayKumar
Python3
# A memoization based recursive program to count numbers
# with difference between odd and even digit sums as 1
# Memnoization based recursive function to count numbers
# with even and odd digit sum difference as 1. This function
# considers leading zero as a digit
def countRec(digits, esum, osum, isOdd, n):
# Base Case
if digits == n:
return (esum - osum == 1)
# If current subproblem is already computed
if lookup[digits][esum][osum][isOdd] != -1:
return lookup[digits][esum][osum][isOdd]
# Initialize result
ans = 0
# If the current digit is odd,
# then add it to odd sum and recur
if isOdd:
for i in range(10):
ans += countRec(digits + 1, esum,
osum + i, False, n)
# Add to even sum and recur
else:
for i in range(10):
ans += countRec(digits + 1, esum + i,
osum, True, n)
# Store current result in lookup table
# and return the same
lookup[digits][esum][osum][isOdd] = ans
return ans
# This is mainly a wrapper over countRec. It
# explicitly handles leading digit and calls
# countRec() for remaining digits.
def finalCount(n):
global lookup
# Initialize number digits considered so far
digits = 0
# Initialize all entries of lookup table
lookup = [[[[-1, -1] for i in range(500)]
for j in range(500)]
for k in range(50)]
# Initialize final answer
ans = 0
# Initialize even and odd sums
esum = 0
osum = 0
# Explicitly handle first digit and call
# recursive function countRec for remaining digits.
# Note that the first digit is considered as even digit
for i in range(1, 10):
ans += countRec(digits + 1, esum + i,
osum, True, n)
return ans
# Driver Code
if __name__ == "__main__":
# A lookup table used for memoization.
lookup = []
n = 3
print("Count of %d digit numbers is %d" % (n, finalCount(n)))
# This code is contributed by
# sanjeev2552
C#
// A memoization based recursive
// program to count numbers with
// difference between odd and
// even digit sums as 1
using System;
class GFG
{
// A lookup table used for memoization.
static int [,,,]lookup = new int[50,1000,1000,2];
// Memnoization based recursive
// function to count numbers
// with even and odd digit sum
// difference as 1. This function
// conisders leading zero as a digit
static int countRec(int digits, int esum,
int osum, int isOdd, int n)
{
// Base Case
if (digits == n)
return (esum - osum == 1)?1:0;
// If current subproblem is already computed
if (lookup[digits,esum,osum,isOdd] != -1)
return lookup[digits,esum,osum,isOdd];
// Initialize result
int ans = 0;
// If current digit is odd, then
// add it to odd sum and recur
if (isOdd==1)
for (int i = 0; i <= 9; i++)
ans += countRec(digits+1, esum, osum+i, 0, n);
else // Add to even sum and recur
for (int i = 0; i <= 9; i++)
ans += countRec(digits+1, esum+i, osum, 1, n);
// Store current result in lookup
// table and return the same
return lookup[digits,esum,osum,isOdd] = ans;
}
// This is mainly a wrapper over countRec. It
// explicitly handles leading digit and calls
// countRec() for remaining digits.
static int finalCount(int n)
{
// Initialize number digits considered so far
int digits = 0;
// Initialize all entries of lookup table
for(int i = 0; i < 50; i++)
for(int j = 0; j < 1000; j++)
for(int k = 0; k < 1000; k++)
for(int l = 0; l < 2; l++)
lookup[i,j,k,l] = -1;
// Initializa final answer
int ans = 0;
// Initialize even and odd sums
int esum = 0, osum = 0;
// Explicitly handle first digit and
// call recursive function countRec
// for remaining digits. Note that
// the first digit is considered
// as even digit.
for (int i = 1; i <= 9; i++)
ans += countRec(digits+1, esum + i, osum, 1, n);
return ans;
}
// Driver code
public static void Main(String[] args)
{
int n = 3;
Console.WriteLine("Coutn of "+ n +
" digit numbers is " + finalCount(n));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出:
Count of 3 digit numbers is 54
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。