农夫过河问题C++递归实现
来源:互联网 发布:大学网络怎么办理 编辑:程序博客网 时间:2024/06/05 01:06
一个农夫带着—只狼、一只羊和—棵白菜,身处河的南岸。他要把这
些东西全部运到北岸。他面前只有一条小船,船只能容下他和—件物
品,另外只有农夫才能撑船。如果农夫在场,则狼不能吃羊,羊不能
吃白菜,否则狼会吃羊,羊会吃白菜,所以农夫不能留下羊和白菜自
己离开,也不能留下狼和羊自己离开,而狼不吃白菜。请求出农夫将
所有的东西运过河的方案。
/* * Farmer cross river with wolf, sheep and cabbage * Depth first search implementation. * Author: ProHanziiee * E-mail: huangnanhan@outlook.com * Date: 2017-11-16 */#include <bits/stdc++.h>using namespace std;enum Item{nothing, wolf, sheep, cabbage};map<Item, Item> foodChain;map<Item, Item> reverseFoodChain;set<Item> sideA, sideB;bool check(set<Item> s) { for(auto &x : s) { if(s.find(foodChain[x]) != s.end() || s.find(reverseFoodChain[x]) != s.end()) return false; } return true;}vector<Item> v;map<pair<int, pair<int, Item> >, pair<int, pair<int, Item> > > trace;pair<int, pair<int, Item> > endPath;bool dfs(int dir, Item item, pair<int, pair<int, Item> > path) { if(dir == 0) { // dir = 0 means transfer item(may be nothing) from sideA to sideB if(item != nothing) sideB.insert(item); if((int)sideB.size() == 3) { // Okay, all items have heen transfered from sideA to sideB endPath = path; return true; } if(check(sideB) == true) { endPath = make_pair(path.first + 1, make_pair(1, nothing)); trace[endPath] = path; if(dfs(1, nothing, endPath) == true) return true; } for(int i = 0; i < 3; ++i) { Item tmp = v[i]; if(tmp == item || sideB.find(tmp) == sideB.end()) continue; sideB.erase(sideB.find(tmp)); if(check(sideB) == true) { endPath = make_pair(path.first + 1, make_pair(1, tmp)); trace[endPath] = path; if(dfs(1, tmp, endPath) == true) return true; } sideB.insert(tmp); } sideB.erase(item); } else { // dir = 1 means transfer item(may be nothing) from sideB to sideA if(item != nothing) sideA.insert(item); if(sideA.size() == 3) return false; for(int i = 0; i < 3; ++i) { Item tmp = v[i]; if(tmp == item || sideA.find(tmp) == sideA.end()) continue; sideA.erase(sideA.find(tmp)); if(check(sideA) == true) { endPath = make_pair(path.first + 1, make_pair(0, tmp)); trace[endPath] = path; if(dfs(0, tmp, endPath) == true) return true; } sideA.insert(tmp); } } return false;}void init() { trace.clear(); sideA.clear(); sideB.clear(); foodChain.clear(); reverseFoodChain.clear(); foodChain[wolf] = sheep; reverseFoodChain[sheep] = wolf; foodChain[sheep] = cabbage; reverseFoodChain[cabbage] = sheep; v.clear(); v.push_back(wolf); v.push_back(sheep); v.push_back(cabbage);}void outputItem(Item item) { switch(item) { case wolf: puts("Wolf"); break; case sheep: puts("Sheep"); break; case cabbage: puts("Cabbage"); break; default: puts("Nothing"); }}void outputDirection(int dir) { if(dir == 0) { printf("A -> B with "); } else { printf("B -> A with "); }}void outputTrace() { puts("A is the initial side of river while B is the target side!"); while(endPath != make_pair(-1, make_pair(-1, nothing))) { outputDirection(endPath.second.first); outputItem(endPath.second.second); endPath = trace[endPath]; }}int main() { #ifdef Zonda_R freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif init(); sideA.insert(wolf); sideA.insert(sheep); sideA.insert(cabbage); bool valid = false; for(int i = 0; i < 3; ++i) { Item tmp = v[i]; if(sideA.find(tmp) != sideA.end()) { sideA.erase(sideA.find(tmp)); if(check(sideA) == true) { trace.clear(); endPath = make_pair(0, make_pair(0, tmp)); trace[endPath] = make_pair(-1, make_pair(-1, nothing)); if(dfs(0, tmp, endPath) == true) { valid = true; break; } } sideA.insert(tmp); } } if(valid == true) { outputTrace(); } else { puts("No Solution!"); } return 0;}
阅读全文
0 0
- c实现农夫过河问题
- 农夫过河问题C++递归实现
- 农夫过河问题的c语言实现
- 农夫过河问题实现
- C语言农夫过河问题
- 农夫过河问题算法设计与实现
- 农夫过河问题
- 农夫过河问题
- 农夫过河问题
- 【人工智能】农夫过河问题
- 农夫过河问题
- 农夫过河问题——C语言程序设计(转)
- 农夫过河问题——c语言代码
- 农夫、狼、羊过河问题
- 农夫过河问题的求解
- 农夫过河问题学习笔记
- 农夫过河
- 农夫过河
- android自定义View学习5--绘制顺序
- React Native与WebView的交互
- 安全策略之数据与代码分离原则
- 5.7.20版MYSQL从安装到坑爹
- 数据可视化matplotlib(03) 绘制决策树
- 农夫过河问题C++递归实现
- 第四节 WebGL中的图形变换:旋转、平移和缩放
- 2017 ICPC 青岛重现
- 机器学习笔记之R语言基础篇4
- 232. Implement Queue using Stacks
- 更新Android Studio3.0的错误记录
- NOIP2017提高组总结
- 图论-C语言-foundation-(1)
- unique_ptr的一个实现