POJ-1606 Jugs
来源:互联网 发布:中仕网络 编辑:程序博客网 时间:2024/05/18 03:33
#include <iostream>#include <string>#include <cstdio>#include <queue>#include <cstring>using namespace std;int CA, CB, n; //A桶 B桶容量 n目标容量char STEP[7][10] = {"success", "fill A", "fill B", "empty A", "empty B", "pour A B", "pour B A"}; //最后输出的步骤int sign[1001][1001]; //标记已访问过的ca cb(用next.ca 做横坐标 用next.cb 做纵坐标)struct Step //构建结构体{ int ca; //当前存放的A桶的量 int cb; //当前存放的B桶的量 int step; //标记这是第几步的操作(为后面输出做准备) int process[10000]; //存放当前步骤的序号(上面STEP数组其实已经按着顺序写了)例如第一个操作是 empty A.则 process[0] = 3.}start; //用于存放初始状态queue<Step> water; //存放Step的队列inline void fill_A(Step &temp) //函数1:将A装满{ temp.ca = CA; temp.process[temp.step] = 1; //当前步骤的操作序号存入。 temp.step ++; //step++为下一次的存入操作序号做准备}inline void fill_B(Step &temp) //函数2:将B装满{ temp.cb = CB; temp.process[temp.step] = 2; temp.step ++;}inline void empty_A(Step &temp) //函数3: 将A清空{ temp.ca = 0; temp.process[temp.step] = 3; temp.step ++;}inline void empty_B(Step &temp) //函数4: 将B清空{ temp.cb = 0; temp.process[temp.step] = 4; temp.step ++;}inline void pour_A_B(Step &temp) //函数5: 将A倒入B{ if(temp.ca + temp.cb > CB) //如果A倒入B超过B的容量 { temp.ca -= CB - temp.cb; //A只倒入部分(将B装满的量) temp.cb = CB; //B装满 } else //如果没满出 则将A全倒入B { temp.cb += temp.ca; temp.ca = 0; } temp.process[temp.step] = 5; temp.step ++;}inline void pour_B_A(Step &temp) //函数6: 将B倒入A{ if(temp.ca + temp.cb > CA) //同理函数5 { temp.cb -= CA - temp.ca; temp.ca = CA; } else { temp.ca += temp.cb; temp.cb = 0; } temp.process[temp.step] = 6; temp.step ++;}void bfs() //bfs宽度搜索{ while(!water.empty()) //队列清空 water.pop(); water.push(start); sign[start.ca][start.cb] = 1; //标记初始位置已访问 while(!water.empty()) //如果队列不空 继续循环 { Step now = water.front(); //保存队列的第一个元素 water.pop(); //扔掉当前第一个元素 为下一个元素成第一个元素做准备 for(int i = 1; i <= 6; i ++)//六种操作 按序号分别操作 { Step next = now; //next存储下一个元素 if(i == 1 && next.ca < CA) //优化:如果next.ca(A桶)本来就是满的 再进行fill没有意义 跳过 fill_A(next); else if(i == 2 && next.cb < CB) //优化:如果next.cb(B桶)本来就是满的 再进行fill没有意义 跳过 fill_B(next); else if(i == 3 && next.ca != 0) //优化:如果next.ca(A桶)本来就是空的 再进行empty没有意义 跳过 empty_A(next); else if(i == 4 && next.cb != 0) //优化:如果next.cb(B桶)本来就是空的 再进行empty没有意义 跳过 empty_B(next); else if(i == 5 && next.ca != 0 && next.cb != CB) //优化:如果next.ca(A桶)空的 或者 next.cb(B桶)满的 再pour没有意义 跳过 pour_A_B(next); else if(i == 6 && next.cb != 0 && next.ca != CA) //优化:如果next.cb(B桶)空的 或者 next.ca(A桶)满的 再pour没有意义 跳过 pour_B_A(next); if(sign[next.ca][next.cb]) //如果此状态标记为1 说明被访问过 直接跳过 其实也就防止出现相同状态(即先前已经到达过 没必要前进后又绕回来这个状态) continue; if(next.ca == n || next.cb == n) //如果A桶 或者 B桶 达到目标容量 输出 跳出结束 { for(int j = 0; j < next.step; j ++) //step的作用体现 printf("%s\n", STEP[next.process[j]]); //next.process[j]储存的是操作序号 之后按STEP[x]字符数组的顺序查找输出操作 return; } else { water.push(next); //存入队列(在之前的优化 可以省去很多没必要的重复操作 队列里面的元素少 让时间优 否则超时) sign[next.ca][next.cb] = 1; //标记已访问 } } }}int main(){ while(~scanf("%d %d %d", & CA, & CB, & n)) //输入(个人感言:就是这里脑残...) { start.ca = 0; //初始化A桶 start.cb = 0; //初始化B桶 start.step = 0; //初始化步骤数 memset(start.process, 0, sizeof(start.process)); //初始化步骤序号数组 memset(sign, 0, sizeof(sign)); //初始化标记数组 bfs(); printf("%s\n", STEP[0]); //输出成功 } return 0; //做人嘛 开心就好}
题意:给2桶水。一桶A 一桶B 。AB桶都有最大容量。A的容量小于B容量。之后输入CA CB N 三个数。CA CB分别代表A桶 B桶的容量。N代表目标容量(小于等于B桶)。输出A桶或者B桶装到了目标容量的步骤。总共有六种步骤。1.将A桶装满(fill A)2.将B桶装满(fill B)3.清空A桶(empty A)4.清空B桶(empty B)5.将A倒入B(如果B满了则停止倒入 A中有剩余)(pour A B)6.将B倒入A(如果A满了则停止倒入 B中有剩余)(pour B A)
题解:第一次比较完美的写出了bfs。一气呵成吧。输入小数据都是对的。不过大数据就超时。为此得剪枝。我一开始很纳闷该怎么剪。后来还是想到了标记数组。还有就是每一步的剪枝。最后完成了上面那种完全体...总耗时一个下午...(最后居然还因为while(sanf)没写成while(~scanf)超时 醉人...检查出来也是哭笑不得..)
0 0
- poj 1606 Jugs
- poj 1606 Jugs (BFS)
- POJ 1606 Jugs
- poj 1606 Jugs
- POJ 1606 Jugs
- poj 1606 Jugs
- POJ-1606 Jugs
- POJ 1606 Jugs 倒水问题
- poj 1606 || hdu 1415 Jugs
- ZOJ 1005 POJ 1606 Jugs /数论
- POJ 1606 && HDU 1415 Jugs(机智)
- POJ 1606 Jugs 已被翻译
- zoj 1005 Jugs || poj 1606 (广搜做法~~~~)
- POJ 1606 Jugs(BFS:找最短路径并输出)
- poj 1606 Jugs(广搜BFS+路径输出)
- hdu1415和poj 1415 Jugs
- poj 1606 Jugs and poj 3414 Pots(数组模拟BFS) uva 571 (数论)
- Jugs
- Codeforces Round #299 (Div. 2) Tavas and Karafs(二分)
- HDOJ1021
- android--onLayout源码 流程 思路详解
- HDU 5237 Base64 (Java大法好)
- 华为OJ(杨辉三角变形)
- POJ-1606 Jugs
- HDOJ 5360 优先队列&简单线段树
- 如何防止自己的IP地址泄漏
- hibernate 数据库事物并发处理
- ActionScript 3.0 学习(五) AS3 Losder加载图片以及显示对象遮罩介绍
- git学习之旅(五)——分支(branch)
- Java中extends 与 implement 区别(转)
- 连续子数组的最大和
- Shuffle'm Up