1314. 稳定的数字

Description

  定义一种操作,经过该操作,可以得到一个数中所有数字的乘积(原数至少要是个两位数)。比如679经过一次操作可以得到378。  你的任务读入一个数,计算经过一次操作得到它的最小的数是多少。
  Input

  仅一行,表示一个十进制数。数的长度可能到达1000位。

Output

  经过一次操作可以得到这个数的最小的数。如果没有这样的数,输出“There is no such number.”(不包括引号)

Sample Input

输入1:

0

输入2:

18

输入3:

51

Sample Output

输出1:

10

输出2:

29

输出3:

There is no such number.

解题思路:这道题目数字虽然比较大0≤这个十进制数<101001,至多有1000位,但是我们还是可以做的,因为它求的是原来最小符合的数,然后我们知道这个运算的结果是这个数中所有数字的乘积,我们以此知道要分解质因数,又因为每一位数都是要小于10的,所以只能用10以内的质数来分解,如果最后剩下一个不是1的话就说明无解,因为要最小的数,所以要让它数位少,数字小,我们以此知道要让它后面的数字要尽量大,这样的话它的位数就会变少了,它的前面几位就会小,如果这个数是一位数的话,要在这个数的前面加上1就变成两位数,变成符合题目要求的数了。
代码如下:(仅供参考,请不要copy)

#include<cstdio>
#include<cstring> 
#include<algorithm> 
#define u(i,x,y) for(int i=x;i<=y;i++)
#define d(i,x,y) for(int i=x;i>=y;i--)
using namespace std; 
char n[1001]; 
int s[1001],f[8],ans[1000],tot=0;  
int cmp(const int &a,const int &b)
{
    return a<b;
}
int work(int x) 
{         
    int temp[1001],k=0;         
    temp[0]=s[0];         
    d(i,s[0],1)       
    {                 
        int dd=(k*10+s[i]);                 
        temp[i]=dd/x;                 
        k=dd % x;         
    }        
    while(temp[temp[0]]==0) temp[0]--;        
    if(k==0)         
    {             
       for(int i=1;i<=temp[0];i++) s[i]=temp[i];             
       s[0]=temp[0];f[x]++;             
       return 1;         
    }
    else return 0; 
}  
int main()
{         
    scanf("%s",n);         
    int len=strlen(n);         
    d(i,len+1,1) n[i]=n[i-1];         

    u(i,1,len) s[i]=int(n[len+1-i]-48);         
    s[0]=len;         
    if(s[0]==1) {printf("1%d",s[1]);return 0;}  

    while(work(2))  work(2);    

    while(work(3))  work(3);

    while(work(5))  work(5); 

    while(work(7))  work(7);

    if(s[0]>1) {printf("There is no such number.\n");return 0;}   

    int dui2=0,dui3=0;         
    dui2=f[2]/3;dui3=f[3]/2;  

    u(i,1,dui2) ans[++tot]=2*2*2; 

    u(i,1,dui3) ans[++tot]=3*3;

    u(i,1,f[5]) ans[++tot]=5; 

    u(i,1,f[7]) ans[++tot]=7;

    f[2]=f[2]%3;f[3]=f[3]%2; 

     if(!f[2]) 
       if(f[3])                    
        ans[++tot]=3;   

    if(f[2]==1) 
    {                
      if(f[3])
      {                     
         ans[++tot]=6;
      }
      else ans[++tot]=2;   
    }
    if(f[2]==2) 
    {                
       if(f[3])                     
       {                             
          ans[++tot]=2;                             
          ans[++tot]=6;                     
       }
       else ans[++tot]=4;   
    }
    sort(ans+1,ans+tot+1,cmp);         
    u(i,1,tot) printf("%d",ans[i]);  
    printf("\n");       
    return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值