C++ 欺骗号码
问题陈述包括检查给定的数字N是否为欺骗数字。这个数字将是用户输入。
欺骗数字 是一个合数,其各不相同的质因数的数字和等于合数本身的数字和。由于1不是质数,我们不将1视为各不相同的质数的数字和。如果一个质数是合数的因数超过一次,那么在计算质因数的数字和时只计算一次。
在这个问题中,我们将获得一个大于1的正整数,并且我们的任务是检查提供的数字是否是一个欺骗数字。我们将检查一个数字成为欺骗数字的条件,如果该数字满足所有条件,则它是一个欺骗数字。
让我们通过下面的例子来理解这个问题。
输入
N= 18
输出
No
解释 - 给定数字18的质因数分解为233。其不同的质因数是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必须是奇数,因此我们将迭代一个循环,从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,否则返回false。
示例
//C++ code to check if N is a hoax number or not
#include <bits/stdc++.h>
using namespace std;
//function to store the distinct prime factors of N in vector
void factors(vector<int>& v, int N){
if(N%2==0){ //check if N is divisible by 2
while(N%2==0){ //divide N by 2 until remainder is equal to 0 and update N everytime
N = N/2;
}
v.push_back(2); //store 2 in the vector
}
//N must be odd now so iterate for odd numbers from i=3 to sqrt(N)
for(int i=3;i<=sqrt(N);i += 2){
if(N%i==0){ //if N is divisible by i
while(N%i==0){ //divide N by i until remainder is 0 and update N
N = N/i;
}
v.push_back(i); //store value of i in the vector
}
}
//for the case when N is a prime number greater than 2
if(N>2){
v.push_back(N);
}
}
//function to check sum of digits of distinct prime factors of N and N
bool check(int N){
vector<int> p; //vector to store distinct prime factors of N
factors(p,N); //calling the function to store prime factors of N in vector
if(p[0]==N){ //for the case when N is a prime number
return false;
}
int sum_factors=0; //to store sum of digits of distinct prime factors
//to calculate sum of digits of prime factors
for(int i=0;i<p.size();i++){
while(p[i]>0){ //adding each digit in the variable using modulo operator
sum_factors += p[i]%10;
p[i]=p[i]/10;
}
}
int sum_number=0; //to store sum of digits of N
//to calculate sum of digits of N
while(N>0){
sum_number += N%10; //adding each digit using modulo 10
N /=10; //dividing N by 10 to get the next digit
}
if(sum_factors==sum_number){ //N is a hoax number if sum is equal
return true;
}
else{
return false;
}
}
int main()
{
int N;
N=234;
//calling the function
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
时间复杂度 − O(√N*logN)
空间复杂度 − O(1)
结论
本文讨论了幸灾乐祸数的概念以及一个数被视为幸灾乐祸数的特定条件。我们提出了一个在C++中高效检查给定数是否为幸灾乐祸数的算法,该算法通过计算该数的质因数,然后检查数字之和来实现。
希望您在阅读本文后对该主题有了清晰的认识,并了解了我们的方法。