最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

Question

例题3-5 最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

如果x+x的各个数字之和得到y,就是说x是y的生成元。给出n(1<=n<=100000),
求最小生成元。无解输出0.例如,n=216,121,2005时的解分别是198,0,1979.

Think

  方法一:假设所求生成元记为m,不难发现m<n。换句话说,只需枚举所有的m<n,看看有木有哪个数是n的生成元。此举效率不高,因为每次计算一个n的生成元都需要枚举n-1个数。

  方法二:一次性枚举100000内的所有正整数到数组中,最后查表即可。

Code

/*
	最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
	
	如果x+x的各个数字之和得到y,就是说x是y的生成元。给出n(1<=n<=100000),
	求最小生成元。无解输出0.例如,n=216,121,2005时的解分别是198,0,1979.
*/
#include<iostream>
#include<string.h>
using namespace std;

#define UPPERLIMIT 100000

const int maxn = 100001;
int answer[maxn];

void print(){
	for(int i=0;i<maxn;i++)
		printf("%d\n", answer[i]);
	printf("\n");
}

int main(){
	memset(answer, 0, sizeof(answer));//初始化为所有y元素都没有最小生成元(:置零) 
	int x,tmp,n,item,sum;//sum即y 
	for(x=1;x<=UPPERLIMIT;x++){
		tmp = x;
		sum = 0;
		sum += x;//加上x本身 
		while(tmp>0){
			sum += tmp%10;
			tmp /= 10;
		}
		//printf("x:%d,sum:%d\n", x, sum);//test
		if(sum<=UPPERLIMIT){
			if(x<answer[sum] || answer[sum] == 0){//赋二者的最小值
				answer[sum] = x;	
			} 
		}
	//	printf("[%d]\n", x);//test	
	}
	//print();	//test
	scanf("%d", &n);
	while(n--){
		scanf("%d", &item);//y
		printf("[%d \'s Min Generate Unit] %d\n", item, answer[item]);
	}
	return 0;
} 
/*
测试数据
3
216
121
2005

198
0
1979.
*/

  

猜你喜欢

转载自www.cnblogs.com/johnnyzen/p/9097051.html