📌  相关文章
📜  找出一个数字X,其总和等于N

📅  最后修改于: 2021-05-04 16:55:10             🧑  作者: Mango

给定正数N。我们需要找到一个或多个数字,使得这些数字本身的数字总和等于N。如果没有这样的数字,则打印-1。在这里N \in [1, 1000000000]

例子:

Input : N = 21
Output : X = 15
Explanation : X + its digit sum 
            = 15 + 1 + 5 
            = 21 

Input  : N = 5
Output : -1

Input : N = 100000001
Output : X = 99999937
         X = 100000000

方法1 :(幼稚方法)
我们已经在这里讨论了该方法。该方法可能不适用于N一样大的情况10^9

方法2:(有效)
事实是,对于数字X <= 1000000000,数字的总和永远不会超过100。使用此信息,我们可以在数字的两边遍历范围为0到100的所有可能性,并检查是否X等于N – X的位数之和。所有可能性都将在此范围内。

C++
// CPP program to find x such that
// X + sumOfDigits(X) = N
#include 
#include 
#include 
#include 
using namespace std;
  
// Computing the sum of digits of x
int sumOfDigits(long int x)
{
    int sum = 0;
    while (x > 0) {
        sum += x % 10;
        x /= 10;
    }
    return sum;
}
  
// Checks for 100 numbers on both left
// and right side of the given number to
// find such numbers X such that X + 
// sumOfDigits(X) = N and updates the answer
// vector accordingly
void compute(vector& answer, long int n)
{
    // Checking for all possibilities of 
    // the answer
    for (int i = 0; i <= 100; i++) {
  
        // Evaluating the value on the left 
        // side of the given number
        long int valueOnLeft = abs(n - i) +
                      sumOfDigits(abs(n - i));
  
        // Evaluating the value on the right
        // side of the given number
        long int valueOnRight = n + i + sumOfDigits(n + i);
  
        // Checking the condition of equality 
        // on both sides of the given number N 
        // and updating the answer vector
        if (valueOnLeft == n)
            answer.push_back(abs(n - i));
        if (valueOnRight == n)
            answer.push_back(n + i);
    }
}
  
// Driver Function
int main()
{    
    long int N = 100000001;
  
    vector answer;
    compute(answer, N);
  
    // If no solution exists, print -1
    if (answer.size() == 0)
        cout << -1;
    else {
  
        // If one or more solutions are possible,
        // printing them!
        for (auto it = answer.begin(); it != answer.end(); ++it)
            cout << "X = " << (*it) << endl;
    }
    return 0;
}


Java
// Java program to find x such that
// X + sumOfDigits(X) = N
import java.util.*;
import java.lang.*;
import java.io.*;
  
class GeeksforGeeks {
  
    // Computing the sum of digits of x
    static int sumOfDigits(long x)
    {
        int sum = 0;
        while (x > 0) {
            sum += (x % 10);
            x /= 10;
        }
        return sum;
    }
  
    // Checks for 100 numbers on both left 
    // and right side of the given number to 
    // find such numbers X such that
    // X + sumOfDigits(X) = N and prints solution.
    static void compute(long n)
    {
        long answer[] = new long[100];
        int pos = 0;
  
        // Checking for all possibilities of the answer
        // in the given range
        for (int i = 0; i <= 100; i++) {
  
            // Evaluating the value on the left side of the
            // given number
            long valueOnLeft = Math.abs(n - i) + 
                               sumOfDigits(Math.abs(n - i));
  
            // Evaluating the value on the right side of the
            // given number
            long valueOnRight = (n + i) + sumOfDigits(n + i);
  
            if (valueOnRight == n)
                answer[pos++] = (n + i);
            if (valueOnLeft == n)
                answer[pos++] = Math.abs(n - i);
        }
  
        if (pos == 0)
            System.out.print(-1);
        else
            for (int i = 0; i < pos; i++)
                System.out.println("X = " + answer[i]);
    }
    // Driver Function
    public static void main(String[] args)
    {
        long N = 100000001;
        compute(N);
    }
}


Python3
# Python3 program to find x such that 
# X + sumOfDigits(X) = N 
  
# Computing the sum of digits of x 
def sumOfDigits(x): 
  
    sum = 0; 
    while (x > 0):
        sum += (x % 10); 
        x = int(x / 10); 
    return sum; 
  
# Checks for 100 numbers on both left 
# and right side of the given number 
# to find such numbers X such that 
# X + sumOfDigits(X) = N and prints 
# solution. 
def compute(n): 
  
    answer = []; 
    pos = 0; 
  
    # Checking for all possibilities 
    # of the answer in the given range 
    for i in range(101):
  
        # Evaluating the value on the 
        # left side of the given number 
        valueOnLeft = (abs(n - i) + 
                       sumOfDigits(abs(n - i))); 
  
        # Evaluating the value on the right 
        # side of the given number 
        valueOnRight = (n + i) + sumOfDigits(n + i); 
  
        if (valueOnRight == n): 
            answer.append(n + i); 
        if (valueOnLeft == n): 
            answer.append(abs(n - i)); 
  
    if (len(answer)== 0): 
        print(-1); 
    else:
        for i in range(len(answer)): 
            print("X =", answer[i]);
              
# Driver Code 
N = 100000001; 
compute(N); 
  
# This code is contributed 
# by mits


C#
// C# program to find x such that
// X + sumOfDigits(X) = N
  
using System;
  
public class GFG{
    // Computing the sum of digits of x
    static int sumOfDigits(long x)
    {
        int sum = 0;
        while (x > 0) {
            sum += (int)(x % 10);
            x /= 10;
        }
        return sum;
    }
  
    // Checks for 100 numbers on both left 
    // and right side of the given number to 
    // find such numbers X such that
    // X + sumOfDigits(X) = N and prints solution.
    static void compute(long n)
    {
        long []answer = new long[100];
        int pos = 0;
  
        // Checking for all possibilities of the answer
        // in the given range
        for (int i = 0; i <= 100; i++) {
  
            // Evaluating the value on the left side of the
            // given number
            long valueOnLeft = Math.Abs(n - i) + 
                            sumOfDigits(Math.Abs(n - i));
  
            // Evaluating the value on the right side of the
            // given number
            long valueOnRight = (n + i) + sumOfDigits(n + i);
  
            if (valueOnRight == n)
                answer[pos++] = (n + i);
            if (valueOnLeft == n)
                answer[pos++] = Math.Abs(n - i);
        }
  
        if (pos == 0)
            Console.Write(-1);
        else
            for (int i = 0; i < pos; i++)
                Console.WriteLine("X = " + answer[i]);
    }
    // Driver Function
      
      
    static public void Main (){
        long N = 100000001;
        compute(N);
    }
}


PHP
 0) 
    { 
        $sum += ($x % 10); 
        $x = (int)$x / 10; 
    } 
    return $sum; 
} 
  
// Checks for 100 numbers on both left 
// and right side of the given number 
// to find such numbers X such that 
// X + sumOfDigits(X) = N and prints 
// solution. 
function compute($n) 
{ 
    $answer = array(0); 
    $pos = 0; 
  
    // Checking for all possibilities 
    // of the answer in the given range 
    for ($i = 0; $i <= 100; $i++) 
    { 
  
        // Evaluating the value on the 
        // left side of the given number 
        $valueOnLeft = abs($n - $i) + 
                        sumOfDigits(abs($n - $i)); 
  
        // Evaluating the value on the right 
        // side of the given number 
        $valueOnRight = ($n + $i) + sumOfDigits($n + $i); 
  
        if ($valueOnRight == $n) 
            $answer[$pos++] = ($n + $i); 
        if ($valueOnLeft == $n) 
            $answer[$pos++] =abs($n - $i); 
    } 
  
    if ($pos == 0) 
        echo (-1),"\n"; 
    else
        for ($i = 0; $i < $pos; $i++) 
            echo "X = ", $answer[$i], "\n";
              
} 
  
// Driver Code 
$N = 100000001; 
compute($N); 
  
// This code is contributed 
// by Sach_Code
?>


输出:

X = 100000000
X = 99999937

这种方法的最大复杂度可以是O(100*len)其中len是max(len)= 9的位数。因此,几乎可以说复杂度为O(len)