第一场(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; } } };