SPOJ - DIV15(数论)

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


你可能感兴趣的:(SPOJ - DIV15(数论))