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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值