我的代码(vjudge AC):
//Digital Generator
#include <stdio.h>
#include <string.h>
int ans[105000];
void Generator(){
for(int i=1;i<=100000;i++){
int sum=i,k=i;
while(k>0){//此处不要使用循环变量i!
sum+=k%10;
k=k/10;
}
ans[i]=sum;//sum的生成元为i
}
return ;
}
int main(){
int m,n;
memset(ans,0,sizeof(ans));
scanf("%d",&m);
Generator();
for(int i=1;i<=m;i++){
int p=1;
scanf("%d",&n);
for(int j=1;j<=n;j++){
if(p&&n==ans[j]) {
printf("%d\n",j);
p=0;
break;
}
}//在数组中搜索生成元
if(p) printf("0\n");
}
return 0;
}
枚举生成元时,必须考虑的是数组的范围。
数组下表储存生成元,而数值部分储存生成值。
只知道生成值数据范围为1-100000,那么其生成元范围是多少呢。
已知生成元不会大于生成值,因此枚举范围1-100000是完全可行的。
但要注意“生成值越大,生成元越大”是错误的。
显然在1-100000内,生成值最大的是99999。
刘汝佳的代码:
//Digital Generator(刘汝佳)
#include <stdio.h>
#include <string.h>
int ans[100005];
int main(){
int T,n;
memset(ans,0,sizeof(ans));
scanf("%d",&T);
//打表
for(int i=1;i<=100000;i++){
int sum=i,k=i;
while(k>0){
sum+=k%10;
k=k/10;
}
if(ans[sum]==0||i<ans[sum]) ans[sum]=i;
//未记录y的生成元,或新的生成元更小。这里==0单独写一条是因为可以和无生成元输出0统一
}
while(T--){
scanf("%d",&n);
printf("%d\n",ans[n]);//直接输出,不必搜索
}
return 0;
}
对比分析:
显然大神的打表思路是优越的。
从具体的枚举方法上看,大神的代码也更好。
像我一样枚举生成元,会浪费掉一定的数组空间,后面输出时还需要搜索。
很多细节可以更简洁(例如关于无生成元输出0的处理)。