题目如下:
给定一个只包含数字 [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