📜  以N表示总和所需的最小回文数|套装2

📅  最后修改于: 2021-04-23 20:29:56             🧑  作者: Mango

给定数字N,我们必须找到将N表示为总和所需的回文数最少。
例子

在上一篇文章中,我们讨论了针对该问题的动态编程方法,该方法的时空复杂度为O(N 3/2 )。
Cilleruelo,Luca和Baxter在2016年的一篇研究论文中证明,每个数字都可以表示为在任何b> = 5的基数中最多三个回文的总和(此下限后来提高到3)。有关该定理的证明,请参阅原始论文。如果数字N本身不是回文并且不能表示为两个回文的总和,我们可以通过安全地假定答案为3来利用该定理。
下面是上述方法的实现:

C++
// C++ program to find the minimum number of
// palindromes required to express N as a sum
 
#include 
using namespace std;
 
// A utility for creating palindrome
int createPalindrome(int input, bool isOdd)
{
    int n = input;
    int palin = input;
 
    // checks if number of digits is odd or even
    // if odd then neglect the last digit of input in
    // finding reverse as in case of odd number of
    // digits middle element occur once
    if (isOdd)
        n /= 10;
 
    // Creates palindrome by just appending revers
    // of number to itself
    while (n > 0) {
        palin = palin * 10 + (n % 10);
        n /= 10;
    }
     
    return palin;
}
 
// Function to generate palindromes
vector generatePalindromes(int N)
{
    vector palindromes;
    int number;
 
    // Run two times for odd and even
    // length palindromes
    for (int j = 0; j < 2; j++) {
 
        // Creates palindrome numbers with first half as i.
        // Value of j decides whether we need an odd length
        // or even length palindrome.
        int i = 1;
        while ((number = createPalindrome(i++, j)) <= N)
            palindromes.push_back(number);
    }
 
    return palindromes;
}
 
// Function to find the minimum
// number of palindromes required
// to express N as a sum
int minimumNoOfPalindromes(int N)
{
    // Checking if the number is a palindrome
    string a, b = a = to_string(N);
    reverse(b.begin(), b.end());
    if (a == b)
        return 1;
 
    // Checking if the number is a
    // sum of two palindromes
 
    // Getting the list of all palindromes upto N
    vector palindromes = generatePalindromes(N);
 
    // Sorting the list of palindromes
    sort(palindromes.begin(), palindromes.end());
 
    int l = 0, r = palindromes.size() - 1;
    while (l < r) {
        if (palindromes[l] + palindromes[r] == N)
            return 2;
        else if (palindromes[l] + palindromes[r] < N)
            ++l;
        else
            --r;
    }
 
    // The answer is three if the
    // control reaches till this point
    return 3;
}
 
// Driver code
int main()
{
    int N = 65;
     
    cout << minimumNoOfPalindromes(N);
     
    return 0;
}


Java
// Java program to find the minimum number of
// palindromes required to express N as a sum
import java.util.*;
 
class GFG
{
 
    // A utility for creating palindrome
    static int createPalindrome(int input, int isOdd)
    {
        int n = input;
        int palin = input;
 
        // checks if number of digits is odd or even
        // if odd then neglect the last digit of input in
        // finding reverse as in case of odd number of
        // digits middle element occur once
        if (isOdd % 2 == 1)
        {
            n /= 10;
        }
 
        // Creates palindrome by just appending revers
        // of number to itself
        while (n > 0)
        {
            palin = palin * 10 + (n % 10);
            n /= 10;
        }
 
        return palin;
    }
 
    // Function to generate palindromes
    static Vector generatePalindromes(int N)
    {
        Vector palindromes = new Vector<>();
        int number;
 
        // Run two times for odd and even
        // length palindromes
        for (int j = 0; j < 2; j++)
        {
 
            // Creates palindrome numbers with first half as i.
            // Value of j decides whether we need an odd length
            // or even length palindrome.
            int i = 1;
            while ((number = createPalindrome(i++, j)) <= N)
            {
                palindromes.add(number);
            }
        }
 
        return palindromes;
    }
 
    static String reverse(String input)
    {
        char[] temparray = input.toCharArray();
        int left, right = 0;
        right = temparray.length - 1;
 
        for (left = 0; left < right; left++, right--)
        {
            // Swap values of left and right
            char temp = temparray[left];
            temparray[left] = temparray[right];
            temparray[right] = temp;
        }
        return String.valueOf(temparray);
    }
 
    // Function to find the minimum
    // number of palindromes required
    // to express N as a sum
    static int minimumNoOfPalindromes(int N)
    {
        // Checking if the number is a palindrome
        String a = String.valueOf(N);
        String b = String.valueOf(N);
        b = reverse(b);
        if (a.equals(b))
        {
            return 1;
        }
 
        // Checking if the number is a
        // sum of two palindromes
        // Getting the list of all palindromes upto N
        Vector palindromes = generatePalindromes(N);
 
        // Sorting the list of palindromes
        Collections.sort(palindromes);
 
        int l = 0, r = palindromes.size() - 1;
        while (l < r)
        {
            if (palindromes.get(l) + palindromes.get(r) == N)
            {
                return 2;
            }
            else if (palindromes.get(l) + palindromes.get(r) < N)
            {
                ++l;
            }
            else
            {
                --r;
            }
        }
 
    // The answer is three if the
        // control reaches till this point
        return 3;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int N = 65;
        System.out.println(minimumNoOfPalindromes(N));
    }
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program to find the minimum number of
# palindromes required to express N as a sum
 
# A utility for creating palindrome
def createPalindrome(_input, isOdd):
  
    n = palin = _input
 
    # checks if number of digits is odd or even
    # if odd then neglect the last digit of _input in
    # finding reverse as in case of odd number of
    # digits middle element occur once
    if isOdd:
        n //= 10
 
    # Creates palindrome by just appending revers
    # of number to itself
    while n > 0: 
        palin = palin * 10 + (n % 10)
        n //= 10
     
    return palin
  
# Function to generate palindromes
def generatePalindromes(N):
  
    palindromes = []
 
    # Run two times for odd and even
    # length palindromes
    for j in range(0, 2): 
 
        # Creates palindrome numbers with first half as i.
        # Value of j decides whether we need an odd length
        # or even length palindrome.
        i = 1
        number = createPalindrome(i, j)
        while number <= N:
            palindromes.append(number)
            i += 1
            number = createPalindrome(i, j)
      
    return palindromes
  
# Function to find the minimum
# number of palindromes required
# to express N as a sum
def minimumNoOfPalindromes(N):
  
    # Checking if the number is a palindrome
    b = a = str(N)
    b = b[::-1]
    if a == b:
        return 1
 
    # Checking if the number is a
    # sum of two palindromes
 
    # Getting the list of all palindromes upto N
    palindromes = generatePalindromes(N)
 
    # Sorting the list of palindromes
    palindromes.sort()
 
    l, r = 0, len(palindromes) - 1
    while l < r:
         
        if palindromes[l] + palindromes[r] == N:
            return 2
        elif palindromes[l] + palindromes[r] < N:
            l += 1
        else:
            r -= 1
      
    # The answer is three if the
    # control reaches till this point
    return 3
  
# Driver code
if __name__ == "__main__":
  
    N = 65
    print(minimumNoOfPalindromes(N))
     
# This code is contributed by Rituraj Jain


C#
// C# program to find the
// minimum number of palindromes
// required to express N as a sum
using System;
using System.Collections.Generic;
class GFG{
 
// A utility for creating palindrome
static int createPalindrome(int input,
                            int isOdd)
{
  int n = input;
  int palin = input;
 
  // checks if number of digits
  // is odd or even if odd then
  // neglect the last digit of
  // input in finding reverse
  // as in case of odd number of
  // digits middle element occur once
  if (isOdd % 2 == 1)
  {
    n /= 10;
  }
 
  // Creates palindrome by
  // just appending revers
  // of number to itself
  while (n > 0)
  {
    palin = palin * 10 + (n % 10);
    n /= 10;
  }
 
  return palin;
}
 
// Function to generate palindromes
static List generatePalindromes(int N)
{
  List palindromes = new List();
  int number;
 
  // Run two times for
  // odd and even length
  // palindromes
  for (int j = 0; j < 2; j++)
  {
    // Creates palindrome numbers
    // with first half as i. Value
    // of j decides whether we need
    // an odd length or even length
    // palindrome.
    int i = 1;
    while ((number = createPalindrome(i++,
                                      j)) <= N)
    {
      palindromes.Add(number);
    }
  }
 
  return palindromes;
}
 
static String reverse(String input)
{
  char[] temparray = input.ToCharArray();
  int left, right = 0;
  right = temparray.Length - 1;
 
  for (left = 0;
       left < right; left++, right--)
  {
    // Swap values of left and right
    char temp = temparray[left];
    temparray[left] = temparray[right];
    temparray[right] = temp;
  }
   
  return String.Join("", temparray);
}
 
// Function to find the minimum
// number of palindromes required
// to express N as a sum
static int minimumNoOfPalindromes(int N)
{
  // Checking if the number
  // is a palindrome
  String a = String.Join("", N);
  String b = String.Join("", N);
  b = reverse(b);
   
  if (a.Equals(b))
  {
    return 1;
  }
 
  // Checking if the number is
  // a sum of two palindromes
  // Getting the list of all
  // palindromes upto N
  List palindromes =
            generatePalindromes(N);
 
  // Sorting the list
  // of palindromes
  palindromes.Sort();
 
  int l = 0,
      r = palindromes.Count - 1;
   
  while (l < r)
  {
    if (palindromes[l] +
        palindromes[r] == N)
    {
      return 2;
    }
    else if (palindromes[l] +
             palindromes[r] < N)
    {
      ++l;
    }
    else
    {
      --r;
    }
  }
 
  // The answer is three if the
  // control reaches till this point
  return 3;
}
 
// Driver code
public static void Main(String[] args)
{
  int N = 65;
  Console.WriteLine(minimumNoOfPalindromes(N));
}
}
 
// This code is contributed by Rajput-Ji


输出:
3


时间复杂度:O(√(N)log N)。