题意:给一个数字字符串,要求给出能被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;
}