题目
给定一个只包含数字 [0…9] 的字符串,求使用字符串中的某些字符,构造一个能够被15整除的最大整数。注意,字符串中的每个字符最多只能使用一次。
输入:程序从标准输入读入数据,每行数据由一串数字组成,长度为1到1000。
输出:针对每一行输入,输出一个结果,每个结果占一行。如果无法构造出能够被15整除的整数,请输出impossible。
测试样例:
输入
1
01431
103
输出
impossible
43110
30
解题思路
首先,能被 15 15 15整除的数肯定能被 3 3 3 和 5 5 5 整除,所以个位数必须为 0 0 0或 5 5 5。
将读入的数字存入num[10]
中,表示每一位数字出现几次,
则nums[0]||nums[5]
必须为true
再考虑被3整除,
如果一个数的各个位上数字之和能被3整除,那么这个数能被3整除
所以把各个位数相加得到sum
,考虑三种情况:
-
sum % 3 == 0
那么这个数必然能被15整除(在考虑被3整除之前已经保证能被5整除了)
-
sum % 3 == 1
必须删去1 , 4 , 7 中的一个数,优先较小者。如果不存在1,4,7, 则删除两次2,5,8
-
sum % 3 == 2
必须删去2, 5 , 8 中的一个数,同样优先较小者,但在删除5的时候要注意保证数字0和5两者至少存在一个数,否则不能删除5,改为删除8。
若不存在2,5,8 则删除两次1,4,7
特别注意:
0能被15整除!
代码
偏长,可能存在一些不必要的代码
#include <iostream>
using namespace std;
int nums[10];//存储每个数字出现几次
char s[1000];
void Init()//初始化,读入数据
{
fill(nums,nums+10,0);
int i = 0;
while(s[i]!='\0')
{
if(s[i]>='0' && s[i]<='9')
{
nums[s[i]-'0']++;
}
i++;
}
}
int Sum()
{
int sum = 0;
for(int i=0; i<10;i++)
{
sum+=i*nums[i];
}
return sum;
}
bool Del(int f,int &sum)//删除不被3整除情况下的一个数字
{
if(f==1)
{
if(nums[1])
{
nums[1]--;
sum-=1;
return true;
}
else if(nums[4])
{
nums[4]--;
sum-=4;
return true;
}
else if(nums[7])
{
nums[7]--;
sum-=7;
return true;
}
else {
return false;
}
}
if(f==2)
{
if(nums[2])
{
nums[2]--;
sum-=2;
return true;
}
else if(nums[0]==0?nums[5]>1:nums[5])//保证至少有1个0或5
{
nums[5]--;
sum-=5;
return true;
}
else if(nums[8])
{
nums[8]--;
sum-=8;
return true;
}
else {
return false;
}
}
return false;
}
bool Div()//主函数 返回能否组成被15整除的数
{
int sum = Sum();
while(sum >= 0)
{
if(sum%3==0){
if(nums[0]||nums[5]){
if(sum == 0) nums[0]=1;//防止输出类似0000的结果
return true;
}
return false;
}
else if(sum%3==1){
if(!Del(1,sum))//删除一个数,删除失败则删除两个数
{
bool flag = Del(2,sum)&&Del(2,sum);
if(flag) {
if(sum==0){
if(nums[0]>0) {nums[0]=1;}
else flag = false;
}
}
return flag;
}
}
else if(sum%3==2){
if(!Del(2,sum))//同上
{
bool flag = Del(1,sum)&&Del(1,sum);
if(flag) {
if(sum==0){
if(nums[0]>0) {nums[0]=1;}
else flag = false;
}
}
return flag;
}
}
}
return false;
}
int main()
{
while(scanf("%s",s)!= EOF)
{
Init();
if(Div()&&(nums[0]||nums[5]))//优先保证末尾是0或5,在没有0的情况下取出一个5放在末尾
{
if(nums[0]==0) nums[5]--;
for(int i = 9; i >=0; i--)
{
for(int j = 0; j < nums[i]; j++)
{
cout << (char)('0'+i);
}
}
if(nums[0]==0) cout<<"5";
cout << endl;
}
else cout<< "impossible"<<endl;
fill(s,s+1000,0);
}
return 0;
}