不用滚动数组会超空间,处理了之后又要用各种技巧优化防止超时间。
每个数字k各位上的加和psum与前一个数k-1的加和是有一定关系的:
k%10!=0,则psum++;
k如果是10的倍数,psum-=8
k如果是100的倍数,psum-=17
………………
//SGU 108 Self-numbers II //筛法+枚举 //by night_watcher #include<iostream> #include<cstring> #include<algorithm> using namespace std; #define N 5000 struct NODE{ int ul; int id; int num; } node[N]; int n,m,psum; bool a[64]; bool cmp1(const NODE x,const NODE y){ return x.id<y.id; } bool cmp2(const NODE x,const NODE y){ return x.ul<y.ul; } void cnt(int k){ if(k%10){ psum+=1; return ; } k/=10; psum-=8; while(k%10==0){ psum-=9; k/=10; } return ; } int main(){ int i,j,nid,selfcnt; while(cin>>n>>m){ memset(a,1,sizeof(a)); for(i=0;i<m;i++){ cin>>node[i].id; node[i].ul=i; } sort(node,node+m,cmp1); selfcnt=0; psum=0; nid=0; for(i=1,j=0;i<=n;i++,j=(j+1)%64){ if(a[j]){ selfcnt++; while(selfcnt==node[nid].id){ node[nid++].num=i; } } cnt(i); a[(j+psum)%64]=0; a[j]=1; } sort(node,node+m,cmp2); cout<<selfcnt<<endl; cout<<node[0].num; for(i=1;i<m;i++){ cout<<" "<<node[i].num; } cout<<endl; } return 0; }