题意:给一个数字字符串,要求给出能被15整除的最大的数。
思路:15是3和5的倍数,那么能够被15整除的的数,肯定也是3和5共同的整倍数。
而3和5的倍数,有很有特点,3的倍数要求每位上的数字之和是3的整倍数,而5的倍数要求个位数上是0或者5.
综合其特点,我们就可以找到思路了。。。
如果数字中有即没有0有没有5的话,则该数字不符合条件,
如果每位上的数字之和sum能被3整除,则该数字在个位数是0或5的前提下,按照大小顺序输出即可。
否则要分成sum%3=1和sum%3=2两种情况考虑。
sum%3=1,则sum需要减去1,4,7,10,13。。。。。。
所以我们要从已存在的1..9中找到要删去的数字。
如果没有直接的1,4,7的话,就得找两位数了,然后两位数的数字和符合上述规律。
由于【3.6.9】是3的整倍数,所以他们删除与否并不能改变sum%3=1的状况。
所以,我们就要找比较小的两位数了【2,2】【2,5】【5,5】【2,8】【5,8】【8,8】..
所以【2,5,8】中,只要有一个数字出现两遍,或出现了其中的2个数字,则能整除15的数字就是存在的。
综上所述,【1,4,7】都没有出现【2,5,8】中只出现了一个数字。那么利用所给的数字就不能构造出一个能整数15的数字了,
代码如下:
#include <cstdio> #include <cstring> char c[1005]; int f[12], sum; int check() { if(sum%3==1&&f[1]==0&&f[4]==0&&f[7]==0&&(f[2]+f[5]+f[8]<2)) return 0; if(sum%3==2&&f[2]==0&&f[5]==0&&f[8]==0&&(f[1]+f[4]+f[7]<2)) return 0; return 1; } void solve() { if(sum%3==1) { if(f[1]) --f[1]; else if(f[4]) --f[4]; else if(f[7]) --f[7]; else if(f[2]>=2) f[2]-=2; else if(f[2]&&f[5]) { --f[2]; --f[5]; } else if(f[5]>=2) f[5]-=2; else if(f[2]&&f[8]) { --f[2]; --f[8]; } else if(f[5]&&f[8]) { --f[5]; --f[8]; } else if(f[8]>=2) f[8]-=2; } else if(sum%3==2) { if(f[2]) --f[2]; else if(f[5]) --f[5]; else if(f[8]) --f[8]; else if(f[1]>=2) f[1]-=2; else if(f[1]&&f[4]) { --f[1]; --f[4]; } else if(f[4]>=2) f[4]-=2; else if(f[1]&&f[7]) { --f[1]; --f[7]; } else if(f[4]&&f[7]) { --f[4]; --f[7]; } else if(f[7]>=2) f[7]-=2; } } int main () { int t, last; scanf("%d",&t); while(t--) { scanf("%s",c); int len = strlen(c); memset(f,0,sizeof(f)); for(int i = 0; i < len; ++i) ++f[c[i]-'0']; if(f[0]==0&&f[5]==0) { printf("impossible\n"); continue; } if(f[0]) { --f[0]; last = 0; } else { --f[5]; last = 5; } sum = last; for(int i = 1; i <= 9; ++i) sum+=f[i]*i; if(check()==0) { printf("impossible\n"); continue; } else solve(); int flag = 0; for(int i = 9; i >= 1; --i) for(int j = 0; j < f[i]; ++j) { printf("%d",i); flag = 1; } if(flag) for(int j = 0; j < f[0]; ++j) printf("%d",0); printf("%d\n",last); } return 0; }