给一个数字 n ,(1<=n<=1e18)。让你找一些数字加起来和为 n ,数字个数不超过50个而且数字都是回文数字。
每次找到大小最接近这个数的回文数即可。如6745888可以找到6745476,6960242可以找到6950595。
用大数模拟一下即可。
//#define test #include<bits/stdc++.h> using namespace std; const int Nmax=1e3+7; typedef long long ll; char s[Nmax]; inline int cmp(char *a,char *b,int n,int m) { if(n<m) return -1; else if(n>m) return 1; if(n==m) { for(int i=0;i<n;i++) { if(a[i]<b[i]) return -1; if(a[i]>b[i]) return 1; } } return 0; } inline int check(char *s,int n) { for(int i=0;i<n;i++) { if(s[i]!=s[n-i-1]) return 0; } return -1; } string ans[57]; int ansnum=0; char tmp[Nmax]; inline char* sub(char *s,char *t,int n) { for(int i=0;i<n;i++) { s[i]-=t[i]; s[i]+='0'; } s[n]='\0'; for(int i=n-1;i>=0;i--) { while(s[i]<'0') { s[i]+=10; s[i-1]-=1; } } for(int i=0;i<n;i++) if(s[i]>'0' && s[i]<='9') return s+i; return s; } inline int check2(char *s,int n) { if(s[0]!='1') return 0; for(int i=1;i<n;i++) if(s[i]!='0') return 0; return 1; } int main() { #ifdef test #endif int t; //freopen("j.in","r",stdin); scanf("%d",&t); for(int _=1;_<=t;_++) { printf("Case #%d:\n",_); scanf("%s",s); ansnum=0; memset(tmp,0,sizeof(tmp)); int n=strlen(s); while(!check(s,n)) { if(check2(s,n)) { for(int i=0;i<n-1;i++) tmp[i]='9'; tmp[n-1]='\0'; ans[++ansnum]=string(tmp); s[0]='1',s[1]='\0'; n=strlen(s); break; } int mid=n/2; //printf("n:%d mid:%d\n",n,mid); for(int i=0;i<mid;i++) tmp[i]=tmp[n-i-1]=s[i]; tmp[mid]=s[n-mid-1]; int b=cmp(tmp,s,n,n); //printf("b:%d\n",b); if(b==-1) { tmp[n]='\0'; ans[++ansnum]=string(tmp); strcpy(s,sub(s,tmp,n)); s[n]='\0'; n=strlen(s); } else if(b==0) break; else { int it; if(n&1) it=mid; else it=mid-1; //printf("mid:%d it:%d\n",mid,it); while(it>=0 && cmp(tmp,s,n,n)>0) { while(tmp[it]>'0' && cmp(tmp,s,n,n)>0) { tmp[it]--; tmp[n-it-1]=tmp[it]; } it--; } tmp[n]='\0'; ans[++ansnum]=string(tmp); strcpy(s,sub(s,tmp,n)); s[n]='\0'; } n=strlen(s); } ans[++ansnum]=string(s); printf("%d\n",ansnum); for(int i=1;i<=ansnum;i++) cout<<ans[i]<<"\n"; } return 0; }