用C++编程,使用深度优先算法解决农夫过河问题
时间: 2024-05-13 14:17:03 浏览: 39
农夫过河C++
好的,以下是使用深度优先算法解决农夫过河问题的C++程序:
```c++
#include <iostream>
#include <vector>
using namespace std;
const int LEFT = 0;
const int RIGHT = 1;
const int FARMER = 0;
const int WOLF = 1;
const int GOAT = 2;
const int CABBAGE = 3;
bool visited[2][2][2][2]; // 记录状态是否被访问过
struct State {
int pos[4]; // pos[0]表示农夫所在的岸,pos[1]表示狼所在的岸,pos[2]表示山羊所在的岸,pos[3]表示白菜所在的岸
int step; // 当前状态的步数
vector<int> path; // 记录到达当前状态的路径
};
bool is_valid(int *pos) { // 判断当前状态是否合法
// 如果狼和山羊在一起,且农夫不在场,返回false
if (pos[WOLF] == pos[GOAT] && pos[FARMER] != pos[WOLF]) {
return false;
}
// 如果山羊和白菜在一起,且农夫不在场,返回false
if (pos[GOAT] == pos[CABBAGE] && pos[FARMER] != pos[GOAT]) {
return false;
}
return true;
}
void dfs(State cur, State &goal) {
if (cur.pos[FARMER] == RIGHT &&
cur.pos[WOLF] == RIGHT &&
cur.pos[GOAT] == RIGHT &&
cur.pos[CABBAGE] == RIGHT) { // 到达目标状态
goal = cur;
return;
}
visited[cur.pos[FARMER]][cur.pos[WOLF]][cur.pos[GOAT]][cur.pos[CABBAGE]] = true; // 标记当前状态为已访问
// 枚举农夫可以带的物品
for (int i = 0; i < 4; i++) {
if (cur.pos[i] == cur.pos[FARMER]) { // 当前物品和农夫在同一侧
State next = cur;
next.pos[i] = (next.pos[i] == LEFT ? RIGHT : LEFT); // 移动物品到对岸
next.pos[FARMER] = (next.pos[FARMER] == LEFT ? RIGHT : LEFT); // 农夫也要过河
if (is_valid(next.pos) && !visited[next.pos[FARMER]][next.pos[WOLF]][next.pos[GOAT]][next.pos[CABBAGE]]) { // 如果状态合法且未被访问过
next.step++;
next.path.push_back(i);
dfs(next, goal); // 继续搜索
next.path.pop_back(); // 恢复现场
}
}
}
}
int main() {
State start, goal;
start.pos[FARMER] = start.pos[WOLF] = start.pos[GOAT] = start.pos[CABBAGE] = LEFT; // 初始状态
start.step = 0;
dfs(start, goal); // 搜索
cout << "步数:" << goal.step << endl;
cout << "移动顺序:";
for (int i = 0; i < goal.path.size(); i++) {
if (goal.path[i] == FARMER) {
cout << "农夫";
} else if (goal.path[i] == WOLF) {
cout << "狼";
} else if (goal.path[i] == GOAT) {
cout << "山羊";
} else if (goal.path[i] == CABBAGE) {
cout << "白菜";
}
cout << "->";
}
cout << endl;
return 0;
}
```
程序中使用了结构体`State`来表示状态,其中`pos`数组表示当前物品所在的岸,`step`表示到达当前状态的步数,`path`保存到达当前状态的路径。`visited`数组用来记录状态是否被访问过。
`is_valid`函数用来判断当前状态是否合法,即狼和山羊、山羊和白菜不可以在同一侧。
在`dfs`函数中,首先判断是否到达了目标状态,如果是则直接返回;否则枚举农夫可以带的物品,如果当前物品和农夫在同一侧,则将物品移动到对岸,并将农夫也移动到对岸,然后判断新状态是否合法且未被访问过,如果是则继续搜索。搜索完成后,输出最短步数和移动顺序即可。
注意,在搜索过程中需要注意恢复现场,即将已经移动的物品和农夫移回原来的岸上。
阅读全文