算法入门之生成元(ACM/ICPC Seoul 2005)

145 阅读1分钟
如果一个数x加上x的各位数字的和得到y,就说x是y的生成元。给出一个n(1<=n<=100000),
求它的最小生成元,无解时输出0。

输入
216
输出
198

输入
2005
输出
1979

输入
121
输出
0

首先我们从思路上我们容易想到,我们要找一个数(n)的生成元

这个生成元毫无疑问比这个数(n)小

那么我们只需把1到n-1的所有数都枚举一遍找到就break就行

最后输出相应数据

就像这样


#include<stdio.h>
int main()
{
	int y,i,x,z,sign=0;
	scanf("%d",&y);
	for(i=1;i<y;i++)
	{
		z=i;
		x=i;
		while(i>0)
		{
			x=x+i%10;
			i/=10;
		}
		i=z;
		if(x==y)
		{
			sign=1;
			printf("%d",i);
			break;
		}
	}
	if(sign==0)
	{
		printf("0");
	}
	return 0;
}

但我们仔细一想,这样做的效率并不高,因为每次计算一个n的生成元都需要枚举n-1个数

我们可以换一种思路,我们可以把所有可以是生成元的数从1到100000都算出来他们对应

的数并且把他们存入一个数组且相应的位置下标即为这个数n

这样做相当于我们制作了一个生成元的表格,最后我们只需要查表即可~~~~~~~~~~~~~~~

代码如下

#include<stdio.h>
#include<string.h>
#define max 100005
int num[max];
int main()
{
	int i,n,x,y;
	memset(num,0,sizeof(num));
	for(i=1;i<100005;i++)
	{
		x=i;
		y=i;
		while(x>0)
		{
			y+=x%10;
			x/=10;
		}
		if(num[y]==0||i<num[y])
		{
			num[y]=i;
		}
	}
	scanf("%d",&n);
	printf("%d",num[n]);
	return 0;
}