某数学兴趣小组有 N 位同学,编号为 0 ~ N-1,老师提议举行一个数字默契小测试:首先每位同学想出一个数字,按同学编号存于数组 numbers。每位同学可以选择将自己的数字进行放大操作,每次在以下操作中任选一种(放大操作不限次数,可以不操作):
将自己的数字乘以 2
将自己的数字乘以 3
若最终所有同学可以通过操作得到相等数字,则返回所有同学的最少操作次数总数;否则请返回 -1。
输入:numbers = [50, 75, 100]
输出:5
解释:
numbers[0] * 2 * 3 = 300 操作两次;
numbers[1] * 2 * 2 = 300 操作两次;
numbers[2] * 3 = 300 操作一次。共计操作五次。
输入:numbers = [10, 14]
输出:-1
解释:无法通过操作得到相同数字。
1.
有:class Solution {
public:
// 把一个数字 分成 x *2*2*2*...*3*3*3, 返回{num[i], 2的幂次, 3的幂次}
tuple<int, int, int> getAns(int num){
int x = num;
int cnt_2 = 0;
int cnt_3 = 0;
while(x%2==0){
x/=2;
cnt_2 ++;
}
while(x%3==0){
x/=3;
cnt_3 ++;
}
return {x, cnt_2, cnt_3};
}
int minOperations(vector<int>& numbers) {
int ans = 0;
int n = numbers.size();
int a,b,c;
vector<array<int, 3>> nums(n);
for(int i=0; i<n; i++){
tie(nums[i][0],nums[i][1],nums[i][2]) = getAns(numbers[i]);
}
for(int i=0; i<n-1; i++){
if(nums[i][0]!=nums[i+1][0]){
return -1;
}
}
int max_cnt_2 = 0;
int max_cnt_3 = 0;
for(int i=0; i<n; i++){
max_cnt_2 = max(max_cnt_2, nums[i][1]);
max_cnt_3 = max(max_cnt_3, nums[i][2]);
}
for(int i=0; i<n; i++){
ans += max_cnt_2 - nums[i][1];
ans += max_cnt_3 - nums[i][2];
}
return ans;
}
};