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