/*
若一个合数的质因数分解式逐位相加之和等于其本身逐位相加的和,则称这个数为Smith数。
例如,4937775=3*5*5*65837,而3+5+5+6+5+8+3+7=42,
    4+9+3+7+7+7+5=42,所以493775是Smith数。给定一个正整数N,求大于n的最小Smith数
    01点14分

    输入描述:若干个case 每个case一行代表正整数N,输入0表示结束
    输出描述:大于N的最小Smith数

    输入样例:
    4937774
    0
    输出样例:
    4937775

*/

粘贴代码请粘贴前面的,后面只是方便观看,但是标点不对,网页自动转成中文标点了,内容都一样

#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;


void Fenjie(int a,vector<int> &v)//用于分解质因数,a是需要分解的数,容器v是存储分解出的数字的数组
//设为引用因为后面需要用这个容器里面的内容,当然也可以定义一个指针函数
    {
        
     
        int i=2;//若分解的数小于等于2,则不会进入下面的循环
        for( i=2;i<=a;i++)//质因数至少要等于2,不能是1
        {
            if(a%i == 0)//这里思路是是只寻找当前最小的质因数,另一个因数递归调用这个函数再寻找最小的因数,最小的因数一定是质数
            break;//若找到则退出循环,i归零
        }
       v.push_back(i);//最小的因数存入容器里
       a=a/i;//这里更新a的值,变成另一个因数,
       //也就是下一次待分解的数。
       if (a>1)//作为递归入口(出口),若a=1说明a更新之前本身就是一个质数,在上面循环里找到的最小质因数是它本身
       //这里不用!=1的原因是考虑如果一开始入的a=1,1/2<1,将执行递归,这是不对的,改成>号后将直接存入容器后结束函数
      {   Fenjie(a,v);//处理另一个因数
    
      }
       
    }


    int Smith(vector<int> &v)//找出大于n的最小Smith数,v是数组容器,用来提供给分解因数的函数调用,
    //待分解因数函数返回结果后进行逐位加法用
{
        int n;//n是输入测试数字的临时变量
        int sum;//sum是质因数逐位相加的和
        int sum1;//sum1是数字本身逐位相加
        int pow;//这个变量是用来探测这个数字有多少位,实际上它表示“这个数除以多少小数点会移到这一位右边”
        //这个数都是10的n次方
        vector<int> v1;//题目要求要有多组输入,v1用来保存输入样例
        for(int w=0;;w++)//这个循环用来满足题目多组输入要求,不必深究
    {
        scanf("%d",&n);
        if(n==0)
        {
            break;
        }
        v1.push_back(n);//把输入样例存入v1。注意break和push的顺序
       
    }
for(int q=0;q<v1.size();q++)//这是个大循环,也是用来满足题目,多组输入自然多组输出,可以自行屏蔽这一层循环
  {
     for(int i=v1[q]+1;;i++)//这个循环是核心算法需要,注意这里用的不是n了,而是数组里面的值,
     //这个循环是从比输入的数大1的数开始挨个试是不是Smith数,每次加1
     {
        sum1=0;//每次试数循环要把两个求和变量置零
        
        sum=0;
        for(pow=1;;pow=pow*10)//这个循环是为了确定数字有多少位。即使这个数除以pow的结果为它的最高位数
        {
            if(i/pow <10)//商小于10时目的已经达到,跳出循环,这个pow已经找到
            break;
        }
            int shang;//定义一个商变量,用来存放当前数字除以pow的结果
            int s;//用来村航经过处理后得到的这一位数字

        for(;pow >= 1;pow=pow/10)//这个循环用来求出每一位并且进行累加
        //pow每次循环缩小10倍,需要注意的是,这个=号必须要有,不然会少加个位数
        {
            
            shang=i/pow;//第一次商为高一位,以本例来看就是4,第二次是高两位49,以此类推
        
            s=shang-(shang/10)*10;//减掉商左边的高位,只留下最右边的一位,这里商先除以10小数点左移一位
            //因为是int类型,小数位自动丢弃,再乘以10,变成之前商整十数,如第二次的过程是49/10=4.9->4,4*10=40
            //减去这个整十数就是我们要得的那一位数了
            sum1=sum1+s;//把得到的数累加起来
        }

            //后面该求质因数的逐位求和了
         Fenjie(i,v);//调用分解质因数函数,i还是之前的i,本次试数循环还没完,
         //v再这个函数没调用之前是一个空的容器,由Smith函数参数提供,调用后存储了i的所有质因数
         
     

         for(int m=0;m<v.size();m++)//遍历i的所有质因数
       {
          for(pow=1;;pow=pow*10)//因数的位数还是不确定,故还得重复上面的步骤确定位数
        {
            if(v[m]/pow <10)
            break;
        }
            

        for(;pow >= 1;pow=pow/10)//原理和上面一样
        {
            
            shang=v[m]/pow;
        
            s=shang-(shang/10)*10;
            sum=sum+s;
        }
       }
       v.clear();//这里要先清空容器,因为这里用的是引用,上一次调用容器里面依然存在原来的数据,清空后再进行下一次试数
       if(sum == sum1)//若相等则找到,返回i即可
       {
           return i;
          
       }
     }//试数循环结束括号
  }//这是多组输出循环后括号   
}//函数结束括号
int main()
{
    vector<int> v;
   
  printf("%d\n",Smith(v));
    system("pause");
}

#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;

void Fenjie(int a,vector<int&v)//用于分解质因数,a是需要分解的数,容器v是存储分解出的数字的数组
//设为引用因为后面需要用这个容器里面的内容,当然也可以定义一个指针函数
    {
        
     
        int i=2;//若分解的数小于等于2,则不会进入下面的循环
        fori=2;i<=a;i++)//质因数至少要等于2,不能是1
        {
            if(a%i == 0)//这里思路是是只寻找当前最小的质因数,另一个因数递归调用这个函数再寻找最小的因数,最小的因数一定是质数
            break;//若找到则退出循环,i归零
        }
       v.push_back(i);//最小的因数存入容器里
       a=a/i;//这里更新a的值,变成另一个因数,
       //也就是下一次待分解的数。
       if (a>1)//作为递归入口(出口),若a=1说明a更新之前本身就是一个质数,在上面循环里找到的最小质因数是它本身
       //这里不用!=1的原因是考虑如果一开始入的a=1,1/2<1,将执行递归,这是不对的,改成>号后将直接存入容器后结束函数
      {   Fenjie(a,v);//处理另一个因数
    
      }
       
    }

    int Smith(vector<int&v)//找出大于n的最小Smith数,v是数组容器,用来提供给分解因数的函数调用,
    //待分解因数函数返回结果后进行逐位加法用
{
        int n;//n是输入测试数字的临时变量
        int sum;//sum是质因数逐位相加的和
        int sum1;//sum1是数字本身逐位相加
        int pow;//这个变量是用来探测这个数字有多少位,实际上它表示“这个数除以多少小数点会移到这一位右边”
        //这个数都是10的n次方
        vector<int> v1;//题目要求要有多组输入,v1用来保存输入样例
        for(int w=0;;w++)//这个循环用来满足题目多组输入要求,不必深究
    {
        scanf(%d,&n);
        if(n==0)
        {
            break;
        }
        v1.push_back(n);//把输入样例存入v1。注意break和push的顺序
       
    }
for(int q=0;q<v1.size();q++)//这是个大循环,也是用来满足题目,多组输入自然多组输出,可以自行屏蔽这一层循环
  {
     for(int i=v1[q]+1;;i++)//这个循环是核心算法需要,注意这里用的不是n了,而是数组里面的值,
     //这个循环是从比输入的数大1的数开始挨个试是不是Smith数,每次加1
     {
        sum1=0;//每次试数循环要把两个求和变量置零
        
        sum=0;
        for(pow=1;;pow=pow*10)//这个循环是为了确定数字有多少位。即使这个数除以pow的结果为它的最高位数
        {
            if(i/pow <10)//商小于10时目的已经达到,跳出循环,这个pow已经找到
            break;
        }
            int shang;//定义一个商变量,用来存放当前数字除以pow的结果
            int s;//用来村航经过处理后得到的这一位数字

        for(;pow >= 1;pow=pow/10)//这个循环用来求出每一位并且进行累加
        //pow每次循环缩小10倍,需要注意的是,这个=号必须要有,不然会少加个位数
        {
            
            shang=i/pow;//第一次商为高一位,以本例来看就是4,第二次是高两位49,以此类推
        
            s=shang(shang/10)*10;//减掉商左边的高位,只留下最右边的一位,这里商先除以10小数点左移一位
            //因为是int类型,小数位自动丢弃,再乘以10,变成之前商整十数,如第二次的过程是49/10=4.9->4,4*10=40
            //减去这个整十数就是我们要得的那一位数了
            sum1=sum1+s;//把得到的数累加起来
        }

            //后面该求质因数的逐位求和了
         Fenjie(i,v);//调用分解质因数函数,i还是之前的i,本次试数循环还没完,
         //v再这个函数没调用之前是一个空的容器,由Smith函数参数提供,调用后存储了i的所有质因数
         
     

         for(int m=0;m<v.size();m++)//遍历i的所有质因数
       {
          for(pow=1;;pow=pow*10)//因数的位数还是不确定,故还得重复上面的步骤确定位数
        {
            if(v[m]/pow <10)
            break;
        }
            

        for(;pow >= 1;pow=pow/10)//原理和上面一样
        {
            
            shang=v[m]/pow;
        
            s=shang(shang/10)*10;
            sum=sum+s;
        }
       }
       v.clear();//这里要先清空容器,因为这里用的是引用,上一次调用容器里面依然存在原来的数据,清空后再进行下一次试数
       if(sum == sum1)//若相等则找到,返回i即可
       {
           return i;
          
       }
     }//试数循环结束括号
  }//这是多组输出循环后括号   
}//函数结束括号
int main()
{
    vector<int> v;
   
  printf(%d\n,Smith(v));
    system(“pause”);
}


3 条评论

vbet armenia · 2023年4月16日 下午4:51

Thank you very much for the information

formula55 tj · 2023年4月22日 下午8:19

Very interesting information

bettorshub live · 2023年5月3日 上午9:38

Waiting for news

回复 formula55 tj 取消回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注