题目描述:
输入描述:
输出描述:
样例及解释:
题意:如果一个数能由2的幂和阶乘组成,那么这个数就是powerful number,现给定一个数,问这个数最少由几个幂和阶乘组成,如果这个数不是powerful number就输出-1
思路:如果一个数只由幂组成,那么我们就可以从大到小遍历幂,然后依次减下来即可,但是加入了阶乘,那么就不行了,因为幂的每个值都是大于比他小的幂的和,然后加入了阶乘,就没有了这个性质
所以我选择了爆搜
幂数加上阶乘数小于1e12的数不是很多,因为我是从大到小排序的,所以剩下的值大于当前的后缀和就不行
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<ll> ve;
int ans = 60;
ll arr[65];
bool cmp(ll a, ll b){
return a > b;
}
void dfs(ll x, int a, int sum, int b){
if(x == 0){
ans = min(ans, b);
return ;
}
if(a == sum){
return ;
}
if(x > arr[a]){
return ;
}
if(x >= ve[a]){
dfs(x - ve[a], a+1, sum, b+1);
}
dfs(x, a+1, sum, b);
}
int main(){
ios::sync_with_stdio(false);
ll sum = 1;
for(int i = 1; i * sum <= 1e12; i++){
sum *= i;
ve.push_back(sum);
}
sum = 2;
for(int i = 1; sum <= 1e12; i++){
sum *= 2;
ve.push_back(sum);
}
sort(ve.begin(), ve.end(), cmp);
// for(int i = 0; i < ve.size(); i++){
// cout << ve[i] << endl;
// }
arr[ve.size() - 1] = ve[ve.size() - 1];
for(int i = ve.size() - 2; i >= 0; i--){
arr[i] = arr[i + 1] + ve[i];
}
int t;
cin >> t;
while(t--){
ll x;
cin >> x;
ans = 65;
int n = ve.size();
dfs(x, 0, n, 0);
if(ans != 65){
cout << ans << endl;
}else{
cout << -1 << endl;
}
}
return 0;
}