第一场(B-魔法数字)
题目描述:
链接:https://ac.nowcoder.com/acm/contest/6218/B
来源:牛客网
一天,牛妹找牛牛做一个游戏,牛妹给牛牛写了一个数字n,然后又给自己写了一个数字m,她希望牛牛能执行最少的操作将他的数字转化成自己的。
操作共有三种,如下:
1.在当前数字的基础上加一,如:4转化为5
2.在当前数字的基础上减一,如:4转化为3
3.将当前数字变成它的平方,如:4转化为16
你能帮牛牛解决这个问题吗?
输入:
给定n,m,分别表示牛牛和牛妹的数字。
输出:
返回最少需要的操作数。
示例输入:3,10
示例输出:2
备注:
思路:
广度优先搜索。利用队列实现,对于每个当前数字cur,将其可转换的数字入队(cur+1,cur-1,cur^2),入队的过程中可以使用集合去掉访问过的数字。
注意到从n到m的转化最多需要abs(n-m)次,因此可以利用这个最大值对操作3剪枝。
代码:
#include<bits/stdc++.h>
class Solution {
public:
/**
* 返回最后要输出的答案
* @param n int整型 表示牛牛的数字
* @param m int整型 表示牛妹的数字
* @return int整型
*/
int solve(int n, int m) {
// write code here
queue<int> q;
unordered_set<int> st;
int res = 0;
q.push(n);
st.insert(n);
while(!q.empty()) {
int sz = q.size();
while(sz--) {
int cur = q.front();
if(cur == m) return res;
q.pop();
if(!st.count(cur - 1)) q.push(cur - 1), st.insert(cur - 1);
if(!st.count(cur + 1)) q.push(cur + 1), st.insert(cur + 1);
if(abs(cur * cur - m) <= abs(n - m) && !st.count(cur * cur)) q.push(cur * cur), st.insert(cur * cur);
}
++res;
}
}
};