恶作剧数字

data structurec++programming更新于 2025/5/2 18:52:17

问题陈述包括检查给定的数字 N(即用户输入)是否为恶作剧数字。

恶作剧数字是一个合数,其不同素因数的数字之和等于合数本身的数字之和。由于 1 不是素数,因此我们不将 1 视为不同素数的数字之和。如果素数多次成为合数的因数,则在取素因数的数字之和时仅将其视为一次。

在这个问题中,我们将给出一个大于 1 的正整数,我们的任务是检查提供的数字是否为恶作剧数字。我们将检查一个数字是否为恶作剧数字的条件,如果该数字满足所有条件,则它就是一个恶作剧数字。

让我们通过以下示例来理解这个问题。

输入

N= 18

输出

No

解释− 给定数字(即 18)的质因数分解为 2*3*3。不同的质因数为 2 和 3,其数字之和为 2+3=5。

给定数字的数字之和为 1+8=9。由于数字的各位数字之和不等于不同素数的各位数字之和,因此给定的数字不是恶作剧数字。

输入

N=58

输出

YES

解释− 输入中给定的数字是 58,其素因数分解为 2*29。数字的不同素因数的各位数字之和为 2+2+9=13,给定数字的各位数字之和为 5+8=13。由于总和相等,因此给定的数字是恶作剧数字,因为它满足数字成为恶作剧数字的所有条件。

输入

N=19

输出

No

解释- 输入的数字是 19。恶作剧数字始终是合数,但此处 19 是质数,因此 19 不是恶作剧数字。

让我们通过检查数字是否为恶作剧数字的条件来了解检查数字是否为恶作剧数字的算法。

算法

对于一个数字是恶作剧数字,该数字的数字之和必须等于其不同质因数的数字之和。我们将简单地计算数字的所有不同质因数以获得不同质因数的数字之和。

计算数字的不同质因数:

我们将创建一个函数,该函数返回包含数字的不同质因数的向量。要存储数字的所有不同质因数,我们将遵循以下步骤:

  • 如果数字可以被 2 整除,我们将该数字除以 2,直到它是奇数,并将 2 存储在向量中。

  • 现在 N 必须是奇数,因此我们将在 for 循环中迭代从 i=3 到 i<=sqrt(N)(仅针对奇数)。

  • 现在,如果 N 可以被 i 整除,则继续将 N 除以 i,直到余数等于零,然后将 i 的值存储在向量中。

  • 每次 N 可以被 i 整除时,继续更新 N 的值。

  • 如果 N 是质数且大于 2,则它不能通过上述步骤变为 1,因此我们将使用 if 语句检查 N 的值,如果它大于2、将值存储在向量中。

按照这些步骤,我们将获得给定数字的不同质因数。该数字应该只是一个合数,因此我们将检查存储在向量中的值是否不等于 N 为质数的情况。

否则,我们将在向量中进行迭代,并使用模数运算符计算数字的不同质因数的数字之和。然后,我们将计算数字 N 的数字之和。如果两者之和相等,我们将返回 true,因为它是一个恶作剧数字,否则我们将返回 false。

我们将在我们的方法中使用此算法来检查该数字是否是恶作剧数字。

方法

下面给出了实现算法以检查该数字是否是恶作剧数字的步骤:

  • 我们将创建一个布尔函数来检查该数字是否是恶作剧数字。

  • 初始化一个向量来存储数字 N 的不同素因数。

  • 我们将通过调用我们将创建的另一个函数来更新向量,以获得 N 的不同素因数,按照算法中提到的步骤。

  • 现在我们将检查向量中第一个索引处的值是否等于是否为 N。如果等于 N,则返回 false,因为 N 是素数,而恶作剧数字始终是合数。

  • 如果 N 是合数,则我们将通过在向量中迭代来计算不同素因数的数字之和。我们将使用模数运算符计算素因数的数字,然后将数字除以 10 以获得下一个数字。我们将每个素因数的数字之和存储在一个变量中,以获得所有不同素因数的数字之和。

  • 现在使用相同的逻辑计算数字 N 的数字之和并将其存储在一个变量中。

  • 如果 N 的不同素因数的数字之和与 N 的数字之和相等,则返回 true,因为数字 N 是恶作剧数字,否则返回 false。

示例

//C++ 代码用于检查 N 是否是恶作剧数字

#include <bits/stdc++.h>

using namespace std;

//函数将 N 的不同素因子存储在向量中
void factors(vector<int>& v, int N){
    
    if(N%2==0){ //检查 N 是否能被 2 整除
    
        while(N%2==0){ //将 N 除以 2 直到余数等于 0 并每次更新 N
            N = N/2;
        }
        v.push_back(2); //将 2 存储在向量中
    }
    
    //N 现在必须是奇数,因此对奇数进行迭代,从 i=3 到 sqrt(N)
    for(int i=3;i<=sqrt(N);i += 2){
    
        if(N%i==0){ //如果 N 能被 i 整除
            while(N%i==0){ //将 N 除以 i 直到余数为 0 并更新 N
                N = N/i;
            }
            v.push_back(i); //将 i 的值存储在向量中
        }
    }
    
    //当 N 是大于 2 的素数时
    if(N>2){
        v.push_back(N);
    }
}

//函数检查 N 和 N 的不同素因数的数字和
bool check(int N){
    vector<int> p; //向量存储 N 的不同素因数
    
    factors(p,N); //调用函数将 N 的素因数存储在向量中
    
    if(p[0]==N){ //当 N 为素数时
        return false;
    }
    
    int sum_factors=0; //存储不同素因数的数字和
    
    //计算素因数的数字和
    for(int i=0;i<p.size();i++){
        while(p[i]>0){ //使用模运算符将变量中的每个数字相加
            sum_factors += p[i]%10;
            p[i]=p[i]/10;
        }
    }
    
    int sum_number=0; //存储 N 的数字之和
    
    //计算 N 的数字之和
    while(N>0){
        sum_number += N%10; //使用模 10 将每个数字相加
        N /=10; //将 N 除以 10 得到下一个数字
    }
    
    if(sum_factors==sum_number){ //如果和相等,则 N 为假数字
        return true;
    }
    else{
        return false;
    }

}

int main()
{
    int N;
    N=234;
    
    //调用函数
    if(check(N)==true){
        cout<<N<<" is a hoax number"<<endl;
    }
    else{
        cout<<N<<" is not a hoax number"<<endl;
    }

    return 0;
}

输出

234 is a hoax number

时间复杂度− $\mathrm{O(\sqrt{N}*\log N)}$

空间复杂度− O(1)

结论

本文讨论了恶作剧数字的概念以及数字成为恶作剧数字的具体条件。我们想出了一种有效的 C++ 算法,通过计算数字的质因数,然后检查数字之和来检查给定数字是否为恶作剧数字。

希望您在阅读本文后已经消除了对该主题的所有疑虑并理解了该方法。


相关文章