倒水问题(广度优先搜索)

问题描述:

有两个无刻度标志的水壶,分别可装x升和y升 ( x,y 为整数且均不大于100)的水。设另有一水缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水也可以相互倾倒。已知x升壶为空壶, y升壶为空壶。问如何通过倒水或灌水操作, 用最少步数能在x或y升的壶中量出 z(z ≤ 100)升的水来。

这道题就是广度优先搜索,需要注意的就是判断是否重复。

分析题目所有情况:

                 X向Y倒水,1.X倒空了。

                                     2.X还有剩余。

                 Y向X倒水, 3.Y倒空了。

                                     4.Y还有剩余。

                 X向水缸倒水,5.X空了。

                 Y向水缸倒水,6.Y空了。

                 水缸向X灌水,7.X满水。

                 水缸向Y倒水,8.Y满水。

一共有上述8种可能情况。

定义一个结构体,存储X壶的水量,Y壶的水量,当前的操作次数。

struct state{
int x,y,step;
}f;

这道题在网上看到有用带结构体的队列解决的,觉得挺好的。

代码参考:http://blog.csdn.net/loi_dqs/article/details/48853127

#include 
using namespace std;
int x,y,z;
struct state{
int x,y,step;
}f;
queue q;
bool vis[105][105];
int BFS()
{
    q.push(f);
    vis[f.x][f.y]=1;//已访问过
    while(q.size())//队列中还有元素
    {
        f=q.front();
        q.pop();//队友出队
        if(f.x==z||f.y==z)
            return f.step;
        if(f.x=y-f.y&&vis[f.x-(y-f.y)][y]==0)//x倒给y且x中还有剩余,此时y已装满
               {
                   q.push((state){f.x-(y-f.y),y,f.step+1});
                   vis[f.x-(y-f.y)][y]=1;
               }
               if(f.x=x-f.x&&vis[x][f.y-(x-f.x)]==0)//y倒给x且y中还有剩余
                {
                    q.push((state){x,f.y-(x-f.x),f.step+1});
                    vis[x][f.y-(x-f.x)]=1;
                }
                if(f.y

这道题状态比较多,列举情况的时候写代码要细心一点,思路要清晰。

你可能感兴趣的:(倒水问题(广度优先搜索))