题目描述:
给定一个整数 n,你可以将其中的数字以任意顺序重新排列,组成新的数字(也可以不重排,保留原数字)。
请问能否组合出 30 的倍数,如果可以,则输出满足条件的最大值,否则输出 −1。
例如,对于 210,你可以通过重排得到 201,210,012,021,102,120,其中 120,210 都是 30 的倍数,由于要找最大的,所以答案是 210。
输入格式
一个整数 n。
输出格式
输出能够通过重排得到的最大符合条件的数。
如果不存在,则输出 −1。
数据范围
1≤n≤109
输入样例:
201
输出样例:
210
开始解题:
方法一:常规解法
提示1:如果一个数能够被3整除,那么就代表该数所有分位的和(个位+十位+百位+...)一定是3的倍数,所以无论他怎么排,都一定可以被3整除. 例如:210,201,120,102,021,012都可以被3整除。
提示2:题目要求找最大可能的数,我们把这个数的分位从大到小排序,那么一定可以得到最大的数,而且如果该数的分位有 0 ,那么一定在末尾,也就是个位上,那么此时一定可以被 10 整除。
所以我们只需要先判断该数能否被 3 整除,然后将数排成最大的数,判断是否能被 10 整除。如果都满足就一定为最大可被 30 整除的数了。
#include<bits/stdc++.h>
using namespace std;
// 自定义排序,从大到小排
bool cmp(char low, char high) {
return low>high;
}
int main() {
int n;
cin >> n;
// 把int型转换为string型,存储到str中
string str = to_string(n);
// 如果n不能整除3,那么无论如何排列都不可能整除30,直接退出
if (n % 3 != 0) {
cout << -1 << endl;
return 0;
}
// 如果能够整除,那么就把n组合成最大的数字
else {
sort(str.begin(), str.end(),cmp);
}
// 如果最大数字不能整除10,直接退出
if (stoi(str) % 10 != 0) {
cout << -1 << endl;
return 0;
}
// 如果可以,就把该数化为int型输出
cout << stoi(str) << endl;
return 0;
}
方法二:暴力解法
这种方法需要借助c++提供的 next_permutation 函数,该函数可以实现字符串的全部排列组合。我们可以枚举每一种组合,再使用 stoi 函数把字符串化为整数,判断是否可以被 30 整除。把可以被 30 整除的数字存储起来,最后取出最大值即可。若没有可被 30 整除的数字,则代表不能被 30 整除。因为此题OJ平台所给范围较小,可以使用该方法AC,但是如果数据范围大的话,程序会超时。此题不再给出代码,感兴趣的码友可以亲手试一下。