C,478字节
#define R return
bs(x,v,l,h,r)unsigned x,*v,l,h,*r;{unsigned m;for(;l<=h;){m=(l+h)/2;if(x<v[m])h=m-1;else if(x>v[m])l=m+1;else{*r=m;R 1;}}*r=m;R 0;}
#include<stdlib.h>
unsigned*f(unsigned w){unsigned*u=0,i,k,m,y,z;if(w>1E6||w==0)R u;u=malloc(w*sizeof*u);if(!u)R u;k=0;u[k++]=1;if(w==1)R u;m=u[k++]=2;if(w==2)R u;l:for(i=0,y=0,z=k-1,++m;i<k;y+=bs(m-u[i],u,i+1,z,&z),++i)if(y>1||u[i]+(i+1!=k?u[i+1]:0)>m)break;if(m==0){free(u);u=0;R u;}if(y!=1)goto l;u[k++]=m;if(k< w)goto l;R u;}
现在,在Tio中,只需9秒即可找到10000个值(并在其中打印前100个值)。诀窍是在内部循环中使用的不是线性搜索,而是二进制搜索...以下这些函数具有很好的缩进性和可读性(最后对我来说):
bsCopy(x,v,l,h,r)unsigned x,*v,l,h,*r;
{unsigned m;
for(;l<=h;){m=(l+h)/2;if(x<v[m])h=m-1;else if(x>v[m])l=m+1;else{*r=m;R 1;}}
*r=m;R 0;// in *r if return 0 the min index that fail else the index of find x
}
unsigned*fCopy(unsigned w)
{unsigned*u=0,i,k,m,y,z;
if(w>1E6||w==0)R u;
u=malloc(w*sizeof*u);
if(!u)R u;
k=0;u[k++]=1;if(w==1)R u;
m=u[k++]=2;if(w==2)R u;//below I suppose m-u[i] is in the range (if exist in u) (i+1)..z
l: for(i=0,y=0,z=k-1,++m;i<k;y+=bsCopy(m-u[i],u,i+1,z,&z),++i)
if(y>1||u[i]+(i+1!=k?u[i+1]:0)>m)break;
if(m==0){free(u);u=0;R u;}
if(y!=1)goto l;
u[k++]=m;if(k< w)goto l;
R u;
}