POJ 3414(BFS建树)
2015-08-03 07:35
363 查看
这一题是典型的BFS建树的问题。首先,可选的操作只有FILL,DROP,POUR三种,而这三种又各自衍生出两个分类。那么,我们可以通过这6种操作不断地转换状态。而我们知道,已经得到过得状态再次得到时,就一定会产生圈,得不到最优解。所以利用一个数组储存看这个状态是否已经达到。
对于每一个子状态,枚举所有的操作,将操作过后得到的新状态压进队列。同时储存得到状态的时间和方法。并且更新这棵树。当达到目标状态后,采用前序遍历的办法逐次打印所经历过的操作。
由于用的是枚举,所以代码写得有点繁琐。
对于每一个子状态,枚举所有的操作,将操作过后得到的新状态压进队列。同时储存得到状态的时间和方法。并且更新这棵树。当达到目标状态后,采用前序遍历的办法逐次打印所经历过的操作。
由于用的是枚举,所以代码写得有点繁琐。
#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<queue> using namespace std; bool flag,visited[105][105]; struct situation { int a, b; int time; char last_act[15]; situation *pa; void operator=(situation modol){ a = modol.a; b = modol.b; time = modol.time; pa = modol.pa; strcpy_s(last_act, modol.last_act); return; //重写赋值操作符简化代码 } }tree[105][105]; int a_vol, b_vol, g_vol; queue<situation>list; void print(int a, int b) { if (tree[a][b].pa == NULL)return; else { print(tree[a][b].pa->a, tree[a][b].pa->b); printf("%s\n", tree[a][b].last_act); } return;//前序遍历这棵树构造路径 } void bfs(situation leaf) { situation temp; int tempa, tempb; if (leaf.a == g_vol || leaf.b == g_vol)//达到目标状态,开始输出 { flag = true; cout << leaf.time << endl; print(leaf.a, leaf.b); return; } if (!visited[a_vol][leaf.b])//已经达到过的状态不再重复 { visited[a_vol][leaf.b] = true; temp.a = a_vol; temp.b = leaf.b; strcpy_s(temp.last_act, "FILL(1)"); temp.time = leaf.time + 1; temp.pa = &tree[leaf.a][leaf.b]; tree[a_vol][leaf.b] = temp; list.push(temp); } if (!visited[leaf.a][b_vol]) { visited[leaf.a][b_vol] = true; temp.a = leaf.a; temp.b = b_vol; strcpy_s(temp.last_act,"FILL(2)"); temp.time = leaf.time + 1; temp.pa = &tree[leaf.a][leaf.b]; tree[leaf.a][b_vol] = temp; list.push(temp); } if (!visited[leaf.a][0]) { visited[leaf.a][0] = true; temp.a = leaf.a; temp.b = 0; strcpy_s(temp.last_act, "DROP(2)"); temp.time = leaf.time + 1; temp.pa = &tree[leaf.a][leaf.b]; tree[leaf.a][0] = temp; list.push(temp); } if (!visited[0][leaf.b]) { visited[0][leaf.b] = true; temp.a = 0; temp.b = leaf.b; strcpy_s(temp.last_act, "DROP(1)"); temp.time = leaf.time + 1; temp.pa = &tree[leaf.a][leaf.b]; tree[0][leaf.b] = temp; list.push(temp); } tempa = min(a_vol, leaf.a + leaf.b); tempb = (leaf.b+leaf.a) - tempa; if (!visited[tempa][tempb]) { visited[tempa][tempb] = true; temp.a = tempa; temp.b = tempb; strcpy_s(temp.last_act, "POUR(2,1)"); temp.time = leaf.time + 1; temp.pa = &tree[leaf.a][leaf.b]; tree[tempa][tempb] = temp; list.push(temp); } tempb = min(b_vol, leaf.a + leaf.b); tempa = (leaf.a+leaf.b) - tempb; if (!visited[tempa][tempb]) { visited[tempa][tempb] = true; temp.a = tempa; temp.b = tempb; strcpy_s(temp.last_act, "POUR(1,2)"); temp.time = leaf.time + 1; temp.pa = &tree[leaf.a][leaf.b]; tree[tempa][tempb] = temp; list.push(temp); //枚举各种情况,如果符合条件的即加入队列 } if (list.empty())return;//若队列为空,即进入死循环,不可能达到目的状态 else { temp = list.front(); list.pop(); bfs(temp); } return; } int main() { memset(visited, false, sizeof(visited)); visited[0][0] = true; tree[0][0].a = tree[0][0].b = tree[0][0].time = 0; flag = false; cin >> a_vol >> b_vol >> g_vol; bfs(tree[0][0]); if (!flag)cout << "impossible" << endl; return 0; }
相关文章推荐
- oc笔记
- 数据库的三范式是什么?
- 计算机的储存架构
- 计算机的储存架构
- Spring容器中Bean的生命周期
- 什么是数据库事务(what is database transaction)?
- Java集合数据结构
- 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】
- 2015百度校招面试题
- 【LeetCode-面试算法经典-Java实现】【078-Subsets(子集)】
- 【LeetCode-面试算法经典-Java实现】【073-Climbing Stairs(爬楼梯)】
- Mybatis结合Spring注解自动扫描源码分析
- OSChina 周一乱弹 —— 你的周末是如何过的?
- Scala模式匹配下的赋值语句
- Windows下mysql自动备份的最佳方案
- Windows下mysql自动备份的最佳方案
- 使用jsoup爬虫抓取页面
- DT大数据梦工厂 温故而知新 之17讲
- Windows下Node.js开发入门(1)
- [LeetCode] Fraction to Recurring Decimal