-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
72 lines (68 loc) · 2.5 KB
/
main.cpp
File metadata and controls
72 lines (68 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Source: https://leetcode.com/problems/minimum-operations-to-make-the-integer-zero
// Title: Minimum Operations to Make the Integer Zero
// Difficulty: Medium
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// You are given two integers `num1` and `num2`.
//
// In one operation, you can choose integer `i` in the range `[0, 60]` and subtract `2^i + num2` from `num1`.
//
// Return the integer denoting the **minimum** number of operations needed to make `num1` equal to `0`.
//
// If it is impossible to make `num1` equal to `0`, return `-1`.
//
// **Example 1:**
//
// ```
// Input: num1 = 3, num2 = -2
// Output: 3
// Explanation: We can make 3 equal to 0 with the following operations:
// - We choose i = 2 and subtract 2^2 + (-2) from 3, 3 - (4 + (-2)) = 1.
// - We choose i = 2 and subtract 2^2+ (-2) from 1, 1 - (4 + (-2)) = -1.
// - We choose i = 0 and subtract 2^0+ (-2) from -1, (-1) - (1 + (-2)) = 0.
// It can be proven, that 3 is the minimum number of operations that we need to perform.
// ```
//
// **Example 2:**
//
// ```
// Input: num1 = 5, num2 = 7
// Output: -1
// Explanation: It can be proven, that it is impossible to make 5 equal to 0 with the given operation.
// ```
//
// **Constraints:**
//
// - `1 <= num1 <= 10^9`
// - `-10^9<= num2 <= 10^9`
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <bit>
#include <cstdint>
using namespace std;
// After k steps, output = num1 - k*num2 - 2^i1 - 2^i2 -... (the sum of k 2-powers)
//
// Let x = num1 - k * num2, y is the sum of the 2-powers.
// Denote #bits(x) be the number of bits in x.
// We need at least #bits(x) 2-powers to make output zero; that is k >= #bits(x)
// However, if k > x, then y >= k > x, the output must be negative.
//
// - If num2 is zero, k = #bits(num1).
// - If num2 is positive, x is decreasing.
// We can choose k > x as terminal condition.
// - If num2 is negative, x is increasing.
// Since x grows linearly and #bits(x) grows logarithmically,
// eventually there will be a k such that #bits(x) <= k.
class Solution {
public:
int makeTheIntegerZero(int num1, int num2) {
int64_t x = num1;
if (num2 == 0) return popcount(static_cast<uint64_t>(x));
for (auto k = 1; true; ++k) {
x -= num2;
if (x < k) return -1;
if (popcount(static_cast<uint64_t>(x)) <= k) return k;
}
return -1; // unreachable
}
};