Persistent Numbers

The multiplicative persistence of a number is defined by Neil Sloane (Neil J.A. Sloane in The Persistence of a Number published in Journal of Recreational Mathematics 6, 1973, pp. 97-98., 1973) as the number of steps to reach a one-digit number when repeatedly multiplying the digits. Example:
679 -> 378 -> 168 -> 48 -> 32 -> 6.

That is, the persistence of 679 is 6. The persistence of a single digit number is 0. At the time of this writing it is known that there are numbers with the persistence of 11. It is not known whether there are numbers with the persistence of 12 but it is known that if they exists then the smallest of them would have more than 3000 digits.
The problem that you are to solve here is: what is the smallest number such that the first step of computing its persistence results in the given number?
Input
For each test case there is a single line of input containing a decimal number with up to 1000 digits. A line containing -1 follows the last test case.
Output
For each test case you are to output one line containing one integer number satisfying the condition stated above or a statement saying that there is no such number in the format shown below.
Sample Input
0
1
4
7
18
49
51
768
-1
Sample Output
10
11
14
17
29
77
There is no such number.
2688
描述: 给定一个整数M,求一个最小的整数N满足N每位数的乘积等于M。(M的位数不超过1000)
若不存在这样的整数N,则输出"There is no such number.",最后以输入M=-1结束
思路:贪心+高精度
不妨首先假设这个数存在. 思考:在什么情况下所求数最小呢?可以发现,首先要数位最小,其次要数位的数由高数位到低数位升序排列. 分析可知我们可以使用贪心. 那么我们就可以得到以下的贪心思路:
这里我们要用到大数的除法。举个例子介绍一下大数除法:

比如 524134 除以 123。结果是4261

第一位4的来源是 我们把 524和123对齐,然后进行循环减法,循环了4次,余32,将32134的前三位321继续和123对齐,循环减法2次,余75,把7534的前三位753和123对齐,循环减法6次,余15,将154和123对齐,只能减1次,所以结果是4 2 6 1。(524134不能整除123)

92进行for循环,
若输入的数能被k个i整除,
则将这k个i放到输出队列的末尾,并输入除以k*i;
当输入只剩下一位时,就可以按顺序输出结果了.

这里从9 开始遍历,我们先找出这个数的最大的因子把它尽可能的放到低位(先放个位,再放十位……)因为这样算出来的这个数才是最小的(才符合题目要求),然后输出的时候从2开始遍历(求因子和输出因子遍历顺序是相反的)输出,最终得到的也就是最小的结果。

#include<stdio.h>
#include<string.h>
int main()
{
    
    
    char s1[1010];
    int a[1010],b[1010],x,y,i,j,k,l;
    while(scanf("%s",s1)!=EOF)
    {
    
    
    	k=0;int c[1010]={
    
    0},d[1010];
    	if(s1[0]=='-')
    	break;
    	l=strlen(s1);
    	for(i=0;i<l;i++)
    	a[i]=s1[i]-'0',d[i]=a[i];//存数
    	if(l==1)//如果是一位数直接特判
    	{
    
    
    		printf("1%d",a[0]);
		}
		else
		{
    
    
			int x=0,y=1,f=0,ff=0,t=0,ss;
			for(i=9;i>=2;i--)//循环遍历9~2
		   {
    
    
		  
		   	    y=i;//除y
		   		for(j=0;j<l;j++)
		   		d[j]=a[j];//用d来存a
		      f=0;//标记是否能除尽y也就是i 9~2
		      //模拟除法取余
			for(j=0;j<l;j++)
			{
    
    
				if(j==l-1)//循环结束
				{
    
    
					if(a[j]%y==0)//如果最后余数为0
					{
    
    
						f=1;//标记除尽
						b[t++]=i;//存结果
						ss=1;
						i=i+1;
						break;
					}
				}
				x=a[j]%y;//模拟除法过程,取余
				a[j+1]=a[j+1]+x*10;//下一位+x*10可以模拟除法想想为什么
			}//取余结束
			if(f==1)//如果最后余数为0除尽了
			{
    
    
				x=0;
				//模拟除法存商
				for(k=0;k<l;k++)
	            {
    
    
	            	x=d[k]%y;//用d来算对y的除法把他存到a里面方便下一次计算
	            	//因为d和a是等价的所以把d对y除求的商存入a用来下一次计算
	            	a[k]=d[k]/y;//存商
	            	d[k+1]=d[k+1]+x*10;//模拟除法
				}//存商结束
			}
			else//如果没除尽
			{
    
    
				for(j=0;j<l;j++)
		   		a[j]=d[j];//把刚刚存的d给a因为除不尽所以a不变
			}
		   }
		   int fff=0;
		 for(i=0;i<l;i++)
		 {
    
    
		 	if(i<(l-1)&&a[i]!=0)//有a[i]不为0就是没除尽,不符合题
		 	fff=1;
			if(a[l-1]!=1)//除尽最后肯定为1
			fff=1;
		 }
		if(fff==1)//不存在
		printf("There is no such number.");
		else
		for(i=t-1;i>=0;i--)//逆序输出b
		printf("%d",b[i]);
	}
	printf("\n");
   }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_46381590/article/details/113000603
今日推荐