题目
题意:
新定义的加法是不进位的加法。现在给两个数A和B,可由任意调整一个数的各个位的数字的顺序,但不能有前导0,求最大的加和。
题解:
题目没说都是正数,但姑且这么看吧。
分别统计A和B0~9都有多少个,然后从9~0枚举当前位的加和。
对加和都为9的组合,肯定能选则选,不用担心影响后面8、7……的组合。但是由于不能有前导0,所以最高位最大时(比如8),究竟用1+7还是2+6就不能随便一个了,所以要枚举一下。
注意只有一位的情况,这种时候不用管什么前导0,。结果当然也不能输出前导0.
//Time:218ms //Memory:4128KB //Length:1837B #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <algorithm> using namespace std; #define MAXN 1000005 char s1[MAXN],s2[MAXN],ans[MAXN],ts[MAXN]; int num[2][10],tnum[2][10]; void cal(int len) { int now=1; for(int i=9;i>=0&&now<=len;--i) for(int j=9;j>=0;--j) while(tnum[0][j]&&tnum[1][(i-j+10)%10]) --tnum[0][j],--tnum[1][(i-j+10)%10], ts[now++]=i+'0'; ts[len+1]='\0'; } int main() { //freopen("/home/moor/Code/input","r",stdin); int ncase,len; scanf("%d",&ncase); for(int hh=1;hh<=ncase;++hh) { printf("Case #%d: ",hh); memset(num,0,sizeof(num)); scanf("%s%s",s1,s2); len=strlen(s1); for(int i=0;s1[i];++i) ++num[0][s1[i]-'0'],++num[1][s2[i]-'0']; if(len==1) { printf("%c\n",s1[0]+s2[0]-'0'); continue; } for(int i=9;i>=0;--i) { bool flag=1; for(int j=9;j>=0&&flag;--j) if(j&&(i-j+10)%10&&num[0][j]&&num[1][(i-j+10)%10]) flag=0; if(!flag) { ans[0]='\0'; for(int j=9;j>=0;--j) if(j&&(i-j+10)%10&&num[0][j]&&num[1][(i-j+10)%10]) { memcpy(tnum,num,sizeof(num)); --tnum[0][j],--tnum[1][(i-j+10)%10]; ts[0]=i+'0'; cal(len-1); if(strcmp(ans,ts)<0) strcpy(ans,ts); } break; } } bool flag=1; for(int i=0;ans[i]&&flag;++i) if(ans[i]!='0') printf("%s\n",&ans[i]),flag=0; if(flag) printf("0\n"); } return 0; }