1. 程式人生 > >最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

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

main ret urn brush 需要 %d \n #define light

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.
*/

  

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