从n到m,有-1和*2两种操作。问最少走几步

本文介绍了解决从起点n到达终点m的最短步数问题的两种方法:一是仅使用-1和*2操作逆向求解;二是采用广度优先搜索算法,在考虑-1、+1及*2操作的同时避免重复状态。

从n到m,有-1和*2两种操作。问最少走几步。

这题必须从m来逆向考虑。

#include <>bits/stdc++.h>
using namespace std;
int main(){
	int count =0;
	int m,n;
	cin>>n>>m;
	while(n < m){
		if(m%2)
			m++;
		else 
			m/=2;
		count++;
	}
	cout<<count+n-m<<endl;
}

另一题:从n到m,有-1和+1和*2三种操作。问最少走几步。

后来想了想记忆化搜索真的是行不通的,会重复取状态。

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include<queue>
using namespace std;
int vis[200005];
queue<pair<int,int> > q;
int main(){
	int n,m;
	cin>>n>>m;
	int s=0; 
	q.push(make_pair(n,0));
	while(!q.empty()){
		int fr=q.front().first;
		int p=q.front().second; 
		q.pop();
		if(fr>200000||fr<0) continue;
		if(vis[fr]==1) continue;
		vis[fr]=1;
		if(fr==m){
			s=p;
			break;
		}
		q.push(make_pair(fr-1,p+1));
		q.push(make_pair(fr+1,p+1));
		q.push(make_pair(fr*2,p+1));
	}
	cout<<s<<endl;
}

C++P10570千反田的捷径 暂无评定 CSP-J组 文件IO 传统题 来源 TomAnderson 时间限制 1000ms 内存限制 1024MB 输入文件名 optimality.in 输出文件名 optimality.out 题目描述 "我很好奇!"千反田对一个数字游戏产生了兴趣。 游戏从一个正整数 𝑛 n 开始,目标是到达另一个整数 𝑚 m( 𝑛 ≤ 𝑚 n≤m)。在每一步中,你可以对当前数字执行以下两种操作之一: 将数字加 1。 将数字乘以 2,然后再加上一个固定的非负整数 𝑘 k。 千反田想知道,从 𝑛 n 开始,通过若干次操作到达 𝑚 m 最少需要多少步。 由于她可能会对很多不同的数字组合感到好奇,所以你需要处理多组询。 输入格式 第一行一个正整数 𝑇 T,表示千反田的好奇心发作了 𝑇 T 次。 接下来 𝑇 T 行,每行包含三个整数 𝑛 , 𝑘 , 𝑚 n,k,m,分别代表起始数字、特殊加数目标数字。 输出格式 输出共 𝑇 T 行,每行一个整数,代表对应询最少步数。 input1 复制 4 2 0 5 1 0 3 3 0 5 20 3 207 output1 复制 2 2 2 7 样例解释 1 对于千反田的几次好奇: 从 2 到 5: 2 → × 2 + 0 4 → + 1 5 2 ×2+0 ​ 4 +1 ​ 5,共 2 步。 从 1 到 3: 1 → + 1 2 → + 1 3 1 +12 +1 ​ 3,共 2 步。 从 3 到 5: 3 → + 1 4 → + 1 5 3 +1 ​ 4 +1 ​ 5,共 2 步。 从 20 到 207: 20 → + 1 21 → + 1 22 → + 1 23 → × 2 + 3 49 → × 2 + 3 101 → + 1 102 → × 2 + 3 207 20 +121 +122 +123 ×2+3 ​ 49 ×2+3 ​ 101 +1102 ×2+3 ​ 207,共 7 步。 input2 复制 5 19 0 13246570 2357 8 16777216 192 60 817 11 4 514 998 2 44353 output2 复制 31 1744 188 8 393 数据范围与提示 对于所有数据,满足 1 ≤ 𝑇 ≤ 10 4 1≤T≤10 4 , 1 ≤ 𝑛 ≤ 𝑚 ≤ 10 9 , 0 ≤ 𝑘 ≤ 10 9 1≤n≤m≤10 9 ,0≤k≤10 9 。 每个测试点的具体限制见下表: 测试点编号 n,k,m 特殊性质 1 ∼ 3 1∼3 ≤ 1000 ≤1000 无 4 ∼ 6 4∼6 无 𝑘 = 0 k=0 7 7 无 𝑘 = 1 k=1 8 8 无 𝑘 = 2 k=2 9 ∼ 10 9∼10 无 无
最新发布
09-14
### 实现马在棋盘上的最短路径 对于在 \( n \times m \) 棋盘上寻找马从起始位置 (x, y) 到达任意目标点的最少移动次数题,可以采用广度优先搜索(BFS)算法。该方法适用于此类无权图中的最短路径查找。 #### 广度优先搜索简介 广度优先搜索是一种用于遍历或搜索树状结构或图形数据的方法。它按照节点距离根节点的距离依次访这些节点,在同一层内的节点遵循先进先出原则[^1]。 #### 马的行规则 根据国际象棋规则,马每次跳跃会形成 L 形图案:向前两格再向左/右一格;或者向上/下一格再横向跳动两个单位。因此,当考虑所有可能的方向时,共有八个方向可供探索[^4]。 #### BFS 算法流程 为了计算从源坐标到目的地所需的时间,初始化队列并将初始状态加入其中。接着不断取出当前处理的位置并尝试朝各个合法的新位置前进直到遇到终点为止。每当成功抵达未曾访过的地点,则记录下步数增量,并将其标记为已查看以防重复计数。 以下是 Python 中的具体实现: ```python from collections import deque def minStepToReachTarget(knightPos, targetPos, N): # 定义8种不同方式下的相对位移量 dx = [-2, -1, 1, 2, -2, -1, 1, 2] dy = [1, 2, 2, 1, -1, -2, -2, -1] queue = deque([(knightPos[0], knightPos[1], 0)]) # 起始位置以及对应的步数 visited = [[False]*N for _ in range(N)] # 记录哪些地方已经过 visited[knightPos[0]-1][knightPos[1]-1] = True # 将起点设为True表示已被访过 while queue: cur_x, cur_y, dist = queue.popleft() if cur_x == targetPos[0] and cur_y == targetPos[1]: return dist for i in range(len(dx)): next_x = cur_x + dx[i] next_y = cur_y + dy[i] if isInside(next_x, next_y, N) and not visited[next_x-1][next_y-1]: visited[next_x-1][next_y-1] = True queue.append((next_x, next_y, dist+1)) return -1 # 如果无法达到目的地位返回-1 def isInside(x, y, N): # 辅助函数判断新坐标的合法性 return x >= 1 and x <= N and y >= 1 and y <= N ``` 此代码片段定义了一个名为 `minStepToReachTarget` 的函数接收三个参数——骑士当前位置、目标位置棋盘大小\(N\)。通过维护一个双端队列来进行层次化扩展直至找到解决方案或是确认不存在可行路径[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值