您当前的位置: 首页 >  蓝桥杯

不牌不改

暂无认证

  • 1浏览

    0关注

    422博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

[蓝桥杯][历届试题]九宫重排

不牌不改 发布时间:2021-07-29 19:55:54 ,浏览量:1

题目

题目链接

题解

BFS。

先讲标准做法,对应代码2:

map类型的vis记录某个状态是否经历过;什么是状态,状态就是比如12345678.123.46758,这些string型的数值就对应着一个个状态,即网格中数字和空格的不同排法。

pair 知识点: 队列中结点的类型为pairpair相当于一个结构体里面有两个元素,一个是string类型,另一个是int类型,分别记录状态和到达此状态的步数。pair的第一个元素通过.first访问,第二个元素通过.second访问。 习惯上,我们一般直接将pair typedefPII,类似地,我将pair typedefPSI。另外还习惯上将first definexsecond definey,但是我不习惯。

每次扩展儿子结点都是让空格去上下左右移动,让空格与满足条件的位置上的数交换,插入队列,不断循环直至到达目标状态或无可扩展结点,输出结果。

这个耗时比较卡点,再多点奇奇怪怪的操作就TLE了。

再将最为重要的双向广搜,因为我也是第一次用,所以好好讲讲(虽然没什么好讲的) 对应代码1。

正如它的名字一样,从初始状态和目标状态同时进行BFS,当其中一个搜索搜索到了一个两个搜索都搜索过的状态了,那么从初始状态到目标状态的最小步数就是第一个搜索记录的步数与第二个搜索记录的步数之和。 道理也很简单,不予证明。

会写广搜的,随便扫一眼就会了。

提几点注意:

  • 这里的map类型要保存的是到达某状态的步数,而不仅仅是是否到达过了。
  • 结束条件是同一个字符串在两个map中都存在。

最后一个代码3,随便看看就得了,图一乐,我的垃圾做法。

代码1:双向广搜
// 双向广搜 53s
#include
using namespace std;
typedef long long ll;
typedef pair PSI;

int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int ans = -1;

queue Q1, Q2;

string ss, tt;

map step1, step2;

int main()
{
	cin>>ss>>tt;
	
	Q1.push(PSI(ss, 0));
	Q2.push(PSI(tt, 0));
	step1[ss] = 0;
	step2[tt] = 0;
	
	
	while(!Q1.empty() && !Q2.empty()) {
		if(!Q1.empty()) {
			PSI p = Q1.front();
			Q1.pop();
			
			string pstr = p.first;
			int pstep = p.second;
			int idx = pstr.find('.');
			
			for(int i = 0;i             
关注
打赏
1662186765
查看更多评论
0.0417s