[BFS广搜]数字变换

2024-06-20 15:20
文章标签 bfs 数字 变换

本文主要是介绍[BFS广搜]数字变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述

给定一个包含5个数字(0-9)的字符串,例如 “02943”,请将“12345”变换到它。 你可以采取3种操作进行变换

1. 交换相邻的两个数字

2. 将一个数字加1。如果加1后大于9,则变为0

3. 将一个数字加倍。如果加倍后大于9,则将其变为加倍后的结果除以10的余数。

最多只能用第2种操作3次,第3种操作2次 求最少经过多少次操作可以完成变换。

输入

有最多 100,000 组数据
每组数据就是包含5个数字的字符串

输出

对每组数据,输出将"12345"变换到给定字符串所需要的最少操作步数。如果无法变换成功,输出-1

样例输入

12435
99999
12374

样例输出

1
-1
3

提示

由于测试数据太多,如果对每组数据都从头进行搜索,就会超时。

建议先做预处理,即以“12345”作为初始状态做一遍彻底的广搜,找出“12345”经合法变换能够到达的所有字符串,并记录到达这些字符串各需要多少步操作。

然后对读入的每组数据,在上述预处理记录的结果中进行查询即可。

解题分析

先看看题目的要求,首先给出了一个字符串,然后给出了一些操作,接着题目要求我们对它所给出的一个目标节点,给出从原始字符串到达这个目标节点的最小步数,并且注意到最多有1000,000组数据,这是一个蛮大的值,所以如果我们对于每一个目标节点都进行一个广搜的话,很有可能超时,所以我们可以对数据进行一个预处理,把答案存储在一个地方,当我们要用的时候就直接输出答案即可。

接着,我们想一想这个广搜的策略是什么,首先吧,我们先定义一个结构体辅助我们在广搜的过程中存储一些中间的数据,这个结构体首先要包括一个能容纳5个数字的数组,然后一个到达此目标节点所经过的操作次数,还有两个分别是还能进行几次操作2和操作3。接着正常去用BFS广搜得到答案即可。最后再主程序里面对每个目标节点输出最短次数。

但是这个广搜的过程其实还值得我们去考究,如何正确地去模拟这一过程呢?首先,笔者想说的是,我们在每一步的广搜里应该只并且只能进行一步操作,进行完后我们还要学会回溯,然后包括这个防止重复访问的visited数组也蛮重要的,它起码需要三个维度,具体的细节可以看代码。

代码演示
#include <iostream>
#include <cmath>
//#include <iomanip>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <bitset>
#include <queue>
#include <stack>
#include <cstdlib>
using namespace std;struct Node{int a[5];int step;int op2;int op3;
};bitset<100000> visited[4][3];
int record[100000];int toNum(const Node& n){int t=0;for(int i=0;i<5;i++){t*=10;t+=n.a[i];}return t;
}void bfs(){queue<Node> q;q.push({1,2,3,4,5,0,3,2});visited[3][2][12345]=1;record[12345]=0;while(!q.empty()){Node tmp=q.front();q.pop();int index=toNum(tmp);if(record[index]==-1 || tmp.step<record[index]){record[index]=tmp.step;}tmp.step++;for(int i=0;i<5;i++){int bak=tmp.a[i];if(i+1<5 && tmp.a[i]!=tmp.a[i+1]){swap(tmp.a[i],tmp.a[i+1]);if(visited[tmp.op2][tmp.op3][toNum(tmp)]==0){q.push(tmp);visited[tmp.op2][tmp.op3][toNum(tmp)]=1;}swap(tmp.a[i],tmp.a[i+1]);}if(tmp.op2){tmp.op2--;tmp.a[i]=(tmp.a[i]+1)%10;if(visited[tmp.op2][tmp.op3][toNum(tmp)]==0){q.push(tmp);visited[tmp.op2][tmp.op3][toNum(tmp)]=1;}tmp.op2++;tmp.a[i]=bak;}if(tmp.op3){tmp.op3--;tmp.a[i]=(tmp.a[i]*2)%10;if(visited[tmp.op2][tmp.op3][toNum(tmp)]==0){q.push(tmp);visited[tmp.op2][tmp.op3][toNum(tmp)]=1;}tmp.op3++;tmp.a[i]=bak;}}}
}int main(){memset(record,-1,sizeof(record));bfs();int n;while(cin>>n){cout<<record[n]<<endl;}return 0;
}

这篇关于[BFS广搜]数字变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1078508

相关文章

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

AIGC6: 走进腾讯数字盛会

图中是一个程序员,去参加一个技术盛会。AI大潮下,五颜六色,各种不确定。 背景 AI对各行各业的冲击越来越大,身处职场的我也能清晰的感受到。 我所在的行业为全球客服外包行业。 业务模式为: 为国际跨境公司提供不同地区不同语言的客服外包解决方案,除了人力,还有软件系统。 软件系统主要是提供了客服跟客人的渠道沟通和工单管理,内部管理跟甲方的合同对接,绩效评估,BI数据透视。 客服跟客人

NC 把数字翻译成字符串

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 有一种将字母编码成数字的方式:‘a’->1, ‘b->2’, … , ‘z->26’。 现在给一串数字,返回有多少种可能的译码结果 import java.u

34465A-61/2 数字万用表(六位半)

34465A-61/2 数字万用表(六位半) 文章目录 34465A-61/2 数字万用表(六位半)前言一、测DC/AC电压二、测DC/AC电流四、测电阻五、测电容六、测二极管七、保存截图流程 前言 1、6位半数字万用表通常具有200,000个计数器,可以显示最大为199999的数值。相比普通数字万用表,6位半万用表具有更高的测量分辨率和更高的测量准确度,适用于精度比较高的测