ZOJ 3327 Friend Number
构造。
(1)如果数字中带有$0$:
1.只有个位是$0$,这种情况就是给输入的数字$+10$再输出即可。
2.其余情况就是给输入的数字$+1$再输出即可。
(2)如果数字中没有$0$:
从个位开始一位一位拆掉。如果发现能凑出比某一位大一点点的数字,那么剩下的高位就不动了,再从个位开始构造目前能凑出的最大数字。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<ctime> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-10; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0; while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } char s[2000]; int T,c[20],len; void F(int x,int f) { if(x==1) return ; else if(x==2) c[2]=c[2]+f*1; else if(x==3) c[3]=c[3]+f*1; else if(x==4) c[2]=c[2]+f*2; else if(x==5) c[5]=c[5]+f*1; else if(x==6) c[2]=c[2]+f*1, c[3]=c[3]+f*1; else if(x==7) c[7]=c[7]+f*1; else if(x==8) c[2]=c[2]+f*3; else if(x==9) c[3]=c[3]+f*2; } int G(int x) { if(x==-1) { if(c[9]>=1||c[3]>=2) return 9; if(c[8]>=1||c[2]>=3) return 8; if(c[7]>=1) return 7; if(c[6]>=1||(c[2]>=1&&c[3]>=1)) return 6; if(c[5]>=1) return 5; if(c[4]>=1||c[2]>=2) return 4; if(c[3]>=1) return 3; if(c[2]>=1) return 2; return 1; } else { if(x<2&&(c[2]>=1)) return 2; if(x<3&&(c[3]>=1)) return 3; if(x<4&&(c[4]>=1||c[2]>=2)) return 4; if(x<5&&(c[5]>=1)) return 5; if(x<6&&(c[6]>=1||(c[2]>=1&&c[3]>=1))) return 6; if(x<7&&(c[7]>=1)) return 7; if(x<8&&(c[8]>=1||c[2]>=3)) return 8; if(x<9&&(c[9]>=1||c[3]>=2)) return 9; } } int main() { scanf("%d",&T); while(T--) { memset(s,0,sizeof s); memset(c,0,sizeof c); scanf("%s",s); len=strlen(s); for(int i=0;i<len/2;i++) swap(s[i],s[len-i-1]); int sum=0; for(int i=0;i<len;i++) if(s[i]=='0') sum++; if(sum==0) { bool flag=0; for(int i=0;i<len;i++) { F(s[i]-'0',1); if(G(-1)>s[i]-'0') { flag=1; int num1=G(s[i]-'0'); s[i]=num1+'0'; F(num1,-1); for(int j=0;j<i;j++) { int num=G(-1); if(num==1) break; s[j]=num+'0'; F(num,-1); } break; } else s[i]='1'; } if(flag==0) { s[len]='1'; len++; for(int i=0;i<len;i++) { int num=G(-1); if(num==1) break; s[i]=num+'0'; F(num,-1); } } } else { int pos; if(sum==1&&s[0]=='0') pos=1; else pos=0; int k=1; for(int i=pos;i<len;i++) { int tmp=s[i]-'0'; s[i]=((tmp+k)%10)+'0'; k=(tmp+k)/10; } if(k!=0) s[len]=k+'0', len++; } for(int i=len-1;i>=0;i--) printf("%c",s[i]); printf("\n"); } return 0; }