如果x加上x的各个数字之和得到y,就说x是y的生成元。 给出n(1≤n≤100000),求最小生成元。 无解输出0。 例如,n=216,121,2005时的解分别为198,0,1979。
如果只是求一次解,那么上述解法可以很好的胜任这个工作。但是如果是求多组n的生成元,那个时间上可能就会 超时。这个时候我们就应该想一些办法来解决时耗上的问题,根据计算机系统的Cache的相关知识,我们可以建立一个类似的缓存区( 但是Cache的中文并不是缓存),就求得的中间结果放置在缓存区,下次再求某个数的生成元,直接查表即可。
解法(存在不足之处)
#include <stdio.h>
//求解各个位数字之和
int get_num_sum(int num)
{
int sum = 0 ;
while( num!=0)
{
sum += num%10 ;
num /=10 ;
}
return sum ;
}
//生成元
int main(void)
{
int n , i ;
freopen("input.txt" , "r" , stdin);
freopen("output.txt" , "w" , stdout);
scanf("%d" , &n);
//开始遍历
for( i = 0 ; i < n ; i++)
{
if( n == i+get_num_sum(i))
{
break;
}
}
if( i!=n)
{
printf("n的生成元:%d\n" , i);
}
else
{
printf("0\n");
}
}
如果只是求一次解,那么上述解法可以很好的胜任这个工作。但是如果是求多组n的生成元,那个时间上可能就会 超时。这个时候我们就应该想一些办法来解决时耗上的问题,根据计算机系统的Cache的相关知识,我们可以建立一个类似的缓存区( 但是Cache的中文并不是缓存),就求得的中间结果放置在缓存区,下次再求某个数的生成元,直接查表即可。
#include <stdio.h>
#include <string.h>
#define MAX_NUM 100000
int data[MAX_NUM+1];
//求解各个位数字之和
int get_num_sum(int num)
{
int sum = 0 ;
while( num!=0)
{
sum += num%10 ;
num /=10 ;
}
return sum ;
}
//生成元
int main(void)
{
int n , i ;
freopen("input.txt" , "r" , stdin);
freopen("output.txt" , "w" , stdout);
memset( data , 0 , sizeof(data));
scanf("%d" , &n);
//开始遍历并放入缓存
for( i = 0 ; i <= MAX_NUM ; i++)
{
int ans = i+get_num_sum(i);
//是求最小生成元,所以如果某个数已经存在生成元那个数就是最小生成元
if( ans <= MAX_NUM && data[ans]==0 )
{
data[ans] = i ;
}
}
printf("%d\n" , data[n]);
}