UVa1583 最小生成元
在刘汝佳老师的《算法竞赛入门经典(第2版)》52页例题3-5中看到此题,发现此题并不需要枚举太多,实际上只需要枚举很少的值即可。
原题内容如下
例题 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。
分析
由于每个数位的数字最大为9,那么m位数字之和最大为9m。假设y是m位数,x的位数必然<=m,假设x也是与y相同的m位数,那么x与y的最大差值为9m,由x最小值y-9m开始逐个尝试,最多不超过9*m次即可找到最小x值。根据本题的数据上限,枚举最多不超过54次x值即可。
以下为代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
int main()
{
int n, x, y, m=0, sum, got;
scanf("%d", &n);
y = n;
while(y>0) // 求出y的位数m
{
y /= 10;
m++;
}
got = 0; // 是否得到解
if(n-9*m<=0) x=1;// 处理n-9*m负值的情况
else x=n-9*m;
for(; x<n; x++)
{
sum = 0;
int temp = x;
while(temp>0) // 得到x各个数位之和sum
{
sum += temp%10;
temp /= 10;
}
if(x+sum==n){
got = 1;
break;
}
}
if(got==0) printf("%d\n", 0);
else printf("%d\n", x);
return 0; // 返回
}