• 整除15问题——北理工网教


    题目如下:

    给定一个只包含数字 [0..9] 的字符串,求使用字符串中的某些字符,构造一个能够被15整除的最大整数。注意,字符串中的每个字符最多只能使用一次。 输入:程序从标准输入读入数据,每行数据由一串数字组成,长度为1到1000。 输出:针对每一行输入,输出一个结果,每个结果占一行。如果无法构造出能够被15整除的整数,请输出impossible。

    测试用例

    
    1
    01431
    103
    

    测试用例输出

    
    impossible
    43110
    30
    

    分析:

    首先,能被15整除的数肯定能被15的两个因数3和5整除,因此要求的最大值要满足两个条件:

    1.最低位的数字是5或0

    2.所有数位的数字之和是3的倍数

    解决方法

    因此,可以先计算所给数串的所有数字之和sum, 根据数字之和的不同可以分以下情况讨论:

    • sum % 3 == 0: 此时只需把所有的数字按照从大到小输出即可,输出时需注意:

      • 若0和5同时存在,或只有0,此时按照从大到小直接输出即可
      • 若只有5,则保留一位5,把剩余的数字从大到小输出,最后输出保留的5
    • sum % 3 == 1: 此时分两种情况:

      • 优先删除一位%3 == 1的数字(1,4,7),然后其余数字从大到小输出
      • 若没有%3 == 1 的数字,则删除两位%3 == 2的数字(2,5,8)
    • sum % 3 == 2:也分两种:

      • 优先删除一位%3 == 2的数字(2,5,8),其余数字从大到小输出
      • 若没有%3 == 2的数字,则删除两位%3 == 1的数字

    需要特别注意:删除% 3 == 2的数字, 该数字是5的情况

    Talk is Cheap, show me the code.

      1 /*************************************************************************
      2     > File Name: 15.cpp
      3     > Author: Max
      4     > Mail: I_am_M4x@protonmail.com
      5     > Created Time: 2017年03月29日 星期二 11时16分53秒
      6  ************************************************************************/
      7 #include <iostream>
      8 #include <string>
      9 #include <cstring>
     10 #include <algorithm>
     11 using namespace std;
     12 
     13 int cnt[10];
     14 int o[] = {1, 4, 7}, t[] = {2, 5, 8};
     15 long long int sum;
     16 int one, two;
     17 string num;
     18 
     19 void print()
     20 {
     21     bool flag = 0;
     22 
     23     for(int i = 9; i > 0; i--)
     24         if(cnt[i])
     25         {
     26             flag = 1;
     27             break;
     28         }
     29 
     30     if(!flag)
     31     {
     32         cout<<0<<endl;
     33         return;
     34     }
     35 
     36     flag = 0;
     37     if(!cnt[0])
     38     {
     39         cnt[5]--;
     40         flag = 1;
     41     }
     42 
     43     for(int i = 9; i >= 0; i--)
     44     {
     45         int j = 0;
     46         while(j++ < cnt[i])
     47             cout<<i;
     48     }
     49 
     50 
     51     if(flag)
     52         cout<<5;
     53 
     54     cout<<endl;
     55 }
     56 
     57 int main()
     58 {
     59     while(cin>>num)
     60     {
     61 
     62         memset(cnt, 0, sizeof(cnt));
     63         sum = 0;
     64         one = two = 0;
     65 
     66         for(int i = 0; i < num.length(); i++)
     67         {
     68             int n = num.at(i) - '0';
     69 
     70             if(n % 3 == 1)
     71                 one++;
     72 
     73             if(n % 3 == 2)
     74                 two++;
     75 
     76             sum += n;
     77             cnt[n]++;
     78         }
     79 
     80         if(! (cnt[5] || cnt[0]))
     81         {
     82             cout<<"impossible"<<endl;
     83             continue;
     84         }
     85 
     86         switch(sum % 3)
     87         {
     88             case 0:
     89                 {
     90                     print();
     91                     break;
     92                 }
     93 
     94             case 1:
     95                 {
     96                     if(!one)
     97                     {
     98                         if(two < 2)
     99                             cout<<"impossible"<<endl;
    100 
    101                         else
    102                         {
    103                             int del = 0;
    104                             for(int k = 0; k < 3 && del < 2; k++ )
    105                             {
    106                                 while(cnt[t[k]] && del < 2)
    107                                 {
    108                                     if(t[k] == 5 && cnt[5] == 1 && cnt[8] && !cnt[5])
    109                                             break;
    110 
    111                                     cnt[t[k]]--;
    112                                     del++;
    113                                 }
    114                             }
    115 
    116                             print();
    117                         }
    118                     }
    119 
    120                     else
    121                     {
    122                         int del = 0;
    123                         for(int k = 0; k < 3 && del < 1; k++)
    124                         {
    125                             while(cnt[o[k]] && del < 1)
    126                             {
    127                                 cnt[o[k]]--;
    128                                 del++;
    129                             }
    130                         }
    131 
    132                         print();
    133                     }
    134 
    135                     break;
    136                 }
    137 
    138             case 2:
    139                 {
    140                     if(!two || (two == 1 && cnt[5] == 1))
    141                     {
    142                         if(one < 2)
    143                             cout<<"impossible"<<endl;
    144 
    145                         else
    146                         {
    147                             int del = 0;
    148                             for(int k = 0; k < 3 && del <2; k++)
    149                             {
    150                                 while(cnt[o[k]] && del < 2)
    151                                 {
    152                                     cnt[o[k]]--;
    153                                     del++;
    154                                 }
    155                             }
    156 
    157                             print();
    158                         }
    159                     }
    160 
    161                     else
    162                     {
    163                         int del = 0;
    164                         for(int k = 0; k < 3 && del < 1; k++)
    165                         {
    166                             while(cnt[t[k]] && del < 1)
    167                             {
    168 
    169                                 if(t[k] == 5 && cnt[5] == 1 && cnt[8] && !cnt[0])
    170                                         break;
    171 
    172                                 cnt[t[k]]--;
    173                                 del++;
    174                             }
    175                         }
    176                         print();
    177                     }
    178 
    179                     break;
    180                 }
    181         }
    182     }
    183 
    184     return 0;
    185 }

    这段代码在逻辑上有重叠的地方,Wa了一下午之后思维有点混乱= =

     提供几组比较特殊的测试用例:

    5888 
    550   
    010  
    58888 
    1111115
    2225
    1222225
    50000      
    对应输出为:
    885
    0
    0
    885
    11115
    225
    222225
    0
  • 相关阅读:
    c++好习惯
    mysql:表
    负载均衡
    KBEngine:架构
    skynet的一些运维数据
    Linux学习—LVM快照功能
    跳跃表
    SQL --Chater03 聚合与排序
    SQL --Chapter02 查询基础
    SQL---Chapter01 数据库和SQL
  • 原文地址:https://www.cnblogs.com/WangAoBo/p/6643877.html
Copyright © 2020-2023  润新知