原题链接:蓝桥杯历届试题-九宫重排
解题思路:
主要的思路是利用bfs进行广搜,直到搜寻到最终结果,输出路径长度。
注意事项:
这里需要注意几点与一般的bfs不同的地方。
1. 对于queue中存储的元素类型,一般的bfs是存储点的坐标,但对于此题来说,每次变化的是九宫图,所以每次要存储对应的字符串序列,但由于还要保存路径长度信息,当然,可以选择hash,我这里采用了更加节省的方法,直接将路径长度和字符串组成一个pair存储起来
2. 其中涉及到字符串和九宫图的转化,一定要小心
参考代码:
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#include <unordered_map>
using namespace std;
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { -1, 1, 0 ,0 };
unordered_map<string, bool> Hash;
char** ToMap(string s) {
char** map = new char*[3];
for (int i = 0; i < 3; i++) {
map[i] = new char[3];
}
for (int i = 0; i < s.length(); i++) {
map[i / 3][i % 3] = s[i];
}
return map;
}
string ToString(char** map) {
string s;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
s += map[i][j];
}
}
return s;
}
void Swap(char* a, char* b) {
char tmp = *a;
*a = *b;
*b = tmp;
}
int bfs(string s, string e) {
queue<pair<string, int>> que;
que.push(make_pair(s, 0));
Hash[s] = true;
while (!que.empty()) {
pair<string, int> p = que.front(); que.pop();
string map_s = p.first;
int dist = p.second;
if (map_s == e) {
return dist;
}
char** map = ToMap(map_s);
int index = 0;
for (int i = 0; i < map_s.length(); i++) {
if (map_s[i] == '.') {
index = i;
break;
}
}
int xx = index / 3;
int yy = index % 3;
for (int i = 0; i < 4; i++) {
int nx = xx + dx[i];
int ny = yy + dy[i];
if (nx < 0 || nx>2 || ny < 0 || ny>2) {
continue;
}
Swap(&map[xx][yy], &map[nx][ny]);
string tmpS = ToString(map);
if (Hash.find(tmpS) != Hash.end()) {
Swap(&map[xx][yy], &map[nx][ny]);
continue;
}
Hash[tmpS] = true;
que.push(make_pair(tmpS, dist + 1));
Swap(&map[xx][yy], &map[nx][ny]);
}
}
return -1;
}
int main() {
string start, end;
cin >> start >> end;
cout << bfs(start, end) << endl;
return 0;
}0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复