刚看到题目的时候,第一想法是用循环做,即每次都从1~100000枚举,如果遇到符合条件的就输出即可,但是仔细想想,这样的话每次都要进行n-1次的枚举,要消耗大量时间。
下面是紫书中给出的“打表法”:
可以说,颠覆了我对打表法的认知,没想到活用打表法,可以这样显著降低时间复杂度。
下面先上我根据紫书的提示写的代码:
#include <stdio.h>
int a[100005],i,j;
int main ()
{
int n,t,m;
for(i=1;i<=100000;i++)
{
int sum=0;
t=i;
while(t>0)
{
sum+=t%10;
t/=10;
}
sum+=i;
a[i]=sum;
}
scanf("%d",&n);
for(i=1;i<=n;i++)
{
int judge=1;
scanf("%d",&m);
for(j=1;j<=100000;j++)
{
if(a[j]==m)
{
printf("%d\n",j);
judge=!judge;
break;
}
}
if(judge) printf("0\n");
}
}
害,,这个代码真的是有够笨,,用索引代表生成元,元素的值代表输入的数据,emmmm,这样打表貌似没有什么卵用,因为搜索时还是会从第一个数开始枚举,知道找到最小的生成元。
害,只能说打表了但没完全打表。。。
下面上紫书中的实例代码:
用索引(数组下标)表示输入的数据,数组的值表示最小生成元,只需一次枚举算出所有的最小生成元,对应相应的索引存入数组,输入索引即可得到最小生成元!!!