#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
// 定义上下左右移动的偏移量
constexpr static int dx[] = {0, 1, -1, 0};
constexpr static int dy[] = {1, 0, 0, -1};
// 定义行列数
const int row = 3;
const int column = 4;
// 定义目标状态
const int target[row][column] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 0}};
// 存储每个数字的目标位置
unordered_map<int, pair<int, int>> position;
// 计算曼哈顿距离,用于判断状态是否达到目标状态
int manhattan_distance(const vector<vector<int>>& state) {
int distance = 0;
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j) {
int num = state[i][j];
if (num != 0) {
int target_x = position[num].first;
int target_y = position[num].second;
distance += abs(i - target_x) + abs(j - target_y);
}
}
}
return distance;
}
// 判断当前状态是否为目标状态
bool is_true(const vector<vector<int>>& state) {
return manhattan_distance(state) == 0;
}
// 深度优先搜索
bool dfs(vector<vector<int>>& state, int x, int y, int mx, int my, int num, vector<vector<int>>& pos) {
// 边界条件
if (x < 0 || x >= row || y < 0 || y >= column) return false;
if (state[x][y] != 0) swap(state[x][y], state[mx][my]); // 交换空白块和相邻块的位置
if (is_true(state)) return true; // 如果当前状态已经是目标状态,返回true
if (pos[x][y] == 1) return false; // 如果当前状态已经被访问过,返回false
if (num == 100000) return false; // 限制搜索深度,避免无限递归
pos[x][y] = 1; // 标记当前状态已经被访问
bool flag = false;
for (int i = 0; i < 4; ++i) { // 对当前状态的四个方向进行搜索
int tx = x + dx[i];
int ty = y + dy[i];
flag = flag || dfs(state, tx, ty, x, y, num + 1, pos); // 递归搜索下一个状态
}
pos[x][y] = 0; // 重置访问标记
swap(state[x][y], state[mx][my]); // 恢复原来的状态
return flag; // 返回是否找到解
}
// 判断初始状态是否可解
bool solvable(vector<vector<int>>& initial_state) {
vector<vector<int>> pos(row, vector<int>(column, 0)); // 记录状态是否被访问过
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j) {
position[initial_state[i][j]] = {i, j}; // 记录每个数字的位置
}
}
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j) {
if (initial_state[i][j] == 0) {
pos.assign(row, vector<int>(column, 0)); // 重置访问标记
return dfs(initial_state, i, j, i, j, 0, pos); // 深度优先搜索
}
}
}
return false;
}
int main(){
vector<vector<int>> initial_state = {
{5, 6, 7, 8},
{0, 1, 2, 3},
{4, 9, 10, 11}
};
cout << (solvable(initial_state) ? "True" : "False") << endl;
return 0;
}
华容道问题的dfs实现
最新推荐文章于 2024-05-30 20:15:33 发布