[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

相关文章

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

从去中心化到智能化: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