c++贪婪法实现八数码问题不可以使用STL并进行注释
时间: 2024-01-30 20:02:23 浏览: 65
好的,以下是一个不使用STL的c++贪婪法求解八数码问题的示例代码,并进行了注释说明:
```c++
#include <iostream>
using namespace std;
// 定义目标状态
int target[9] = {1, 2, 3, 8, 0, 4, 7, 6, 5};
// 定义移动的方向,上下左右
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
// 定义状态结构体
struct State {
// 棋盘状态
int board[9];
// 当前空格位置
int zeroPos;
// 当前步数
int step;
// 预估步数
int h;
// 重载小于号运算符,用于优先队列排序
bool operator<(const State& rhs) const {
return step + h > rhs.step + rhs.h;
}
};
// 计算曼哈顿距离
int getManhattanDistance(int x1, int y1, int x2, int y2) {
return abs(x1 - x2) + abs(y1 - y2);
}
// 计算当前状态的预估步数
int estimate(State& state) {
int h = 0;
for (int i = 0; i < 9; i++) {
if (state.board[i] == 0) continue;
int x1 = i / 3, y1 = i % 3;
int x2 = (state.board[i] - 1) / 3, y2 = (state.board[i] - 1) % 3;
h += getManhattanDistance(x1, y1, x2, y2);
}
return h;
}
// 检查当前状态是否为目标状态
bool check(State& state) {
for (int i = 0; i < 9; i++) {
if (state.board[i] != target[i]) return false;
}
return true;
}
// 使用贪婪法求解八数码问题
int solve(State& start) {
// 定义优先队列,用于存储状态
priority_queue<State> q;
q.push(start);
while (!q.empty()) {
// 取出队首状态
State cur = q.top();
q.pop();
// 检查当前状态是否为目标状态
if (check(cur)) {
return cur.step;
}
// 扩展当前状态
int x = cur.zeroPos / 3, y = cur.zeroPos % 3;
for (int d = 0; d < 4; d++) {
int nx = x + dx[d], ny = y + dy[d];
if (nx < 0 || nx >= 3 || ny < 0 || ny >= 3) continue;
int np = nx * 3 + ny;
State next = cur;
next.board[cur.zeroPos] = next.board[np];
next.board[np] = 0;
next.zeroPos = np;
next.step++;
next.h = estimate(next);
q.push(next);
}
}
// 没有解
return -1;
}
int main() {
// 定义起始状态
State start;
for (int i = 0; i < 9; i++) {
cin >> start.board[i];
if (start.board[i] == 0) start.zeroPos = i;
}
start.step = 0;
start.h = estimate(start);
// 求解八数码问题
int ans = solve(start);
cout << ans << endl;
return 0;
}
```
注释中会解释代码中的各个部分的作用和原理。
阅读全文