使用算术运算运算符将数字 N 转换为 M 所需的步骤最少
给定两个整数N和M ,任务是找到将数字N转换为M所需的最小操作数的序列,使得在每个操作中N可以相加(N = N + N) ,减去(N = N – N) ,乘以(N = N*N) ,或除以(N = N/N) 。如果无法将N转换为M ,则打印“-1” 。
例子:
Input: N = 7, M = 392
Output: 3
+, *, +
Explanation:
Following are the operations performed:
- Performing addition modifies the value of N as 7 + 7 = 14.
- Performing multiplication modifies the value of N as 14*14 = 196.
- Performing addition modifies the value of N as 196 + 196 = 392.
After the above sequence of moves as “+*+”, the value of N can be modified to M.
Input: N = 7, M = 9
Output: -1
Explanation: There are no possible sequence of operations to convert N to M.
方法:给定的问题可以通过以下观察来解决:
- 当 N = N – N = 0 时,减法运算总是会得到 0。同样,当 N = N / N = 1 时,除法运算总是会得到 1。因此,这些情况可以轻松处理。
- 对于加法和乘法,可以使用广度优先搜索遍历来解决该问题,方法是按照操作计数的递增顺序为每个操作序列创建一个状态。
解决给定问题的步骤如下:
- 维护一个队列来存储 BFS 状态,其中每个状态包含当前可到达的整数N'和一个表示从N到达N'的操作序列的字符串。
- 最初,将表示N和操作序列为空的状态{N,“”}添加到队列中。
- 将除法操作的状态{1, “/”}也添加到队列中。
- 在广度优先遍历期间,对于每个状态,添加两个状态,其中第一个状态表示加法(N' + N') ,第二个状态表示乘法(N' * N') 。
- 维护一个无序映射来检查当前状态是否已经在 BFS 遍历期间被访问过。
- 如果当前状态的值等于M ,那么直到M所获得的操作序列就是结果。否则,打印“-1” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the sequence of
// minimum number of operations needed
// to convert N into M using +, -, *, /
string changeNtoM(int N, int M)
{
// Case where N and M are same
if (N == M) {
return " ";
}
// Case where M = 0
if (M == 0) {
return "-";
}
// Stores the BFS states in a queue
queue > q;
// Stores if current state is visited
unordered_map visited;
// Initial State
q.push({ N, "" }), visited[N] = 1;
// State where the first operation is /
q.push({ 1, "/" }), visited[1] = 1;
// Loop for the BFS traversal
while (!q.empty()) {
// Stores the current BFS state
pair cur = q.front();
q.pop();
// If the value of current state is
// equal to M return the stored
// sequence of operations
if (cur.first == M) {
// Return answer
return cur.second;
}
// Adding 1st state representing the
// addition operation(N' + N')
if (!visited[cur.first + cur.first]
&& cur.first + cur.first <= M) {
// Add state into queue and
// mark the state visited
q.push({ cur.first + cur.first,
cur.second + "+" });
visited[cur.first + cur.first] = 1;
}
// Adding 2nd state representing the
// multiplication operation(N' * N')
if (!visited[cur.first * cur.first]
&& cur.first * cur.first <= M) {
// Add state into queue and
// mark the state visited
q.push({ cur.first * cur.first,
cur.second + "*" });
visited[cur.first * cur.first] = 1;
}
}
// No valid sequence of operations exist
return "-1";
}
// Driver Code
int main()
{
int N = 7, M = 392;
string result = changeNtoM(N, M);
if (result == "-1")
cout << result << endl;
else
cout << result.length() << endl
<< result;
return 0;
}
输出:
3
+*+
时间复杂度: O(min(2 log 2 (M – N) , M – N))
辅助空间: O((MN)* log 2 (M – N))