倒水问题(BFS)

有装满水的6升的杯子、空的3升杯子和1升杯子, 3个杯子中都没有刻度. 在不使用其他道具的情况下, 是否可以量出4升的水呢

你的任务是解决一般性的问题:设大、中、小3个杯子的容量分别为a,b,c,最初只有大杯子装满水,其他两个杯子为空。最少需要多少步才能让某一个杯子中的水有x升呢?你需要打印出每步操作后各个杯子中的水量(0<c<b<a<1000)

样例输入

样例输出

2

6 3 1 4

9 6 3 1

最少需要3步:(6,0,0)-->(3,3,0)-->(3,2,1)-->(4,2,0)

No

 

话不多说,先上码:

//
// main.cpp
//
// Created by Soildom on 2017/11/18.
// Copyright © 2017年 Soildom. All rights reserved.
//

#include <iostream>
#include <queue>
using namespace std;

const int MAXN=1000;

class node
{
public:
    int cup[3]={0},last=0,depth=0;
};

int vis[MAXN][MAXN],i_cup[3],target;
node v[MAXN];
queue<int> number;

void progress(int x)
{
    if (!x)
    {
        printf("(%d,0,0)-->",i_cup[0]);
        return;
    }
    progress(v[x].last);
    printf("(%d,%d,%d)-->",v[x].cup[0],v[x].cup[1],v[x].cup[2]);
}

void bfs()
{
    int k=0;
    while (!number.empty())
        number.pop();
    v[k].cup[0]=i_cup[0];
    vis[v[k].cup[1]][v[k].cup[2]]=1;
    number.push(k);
    while (!number.empty())
    {
        if ((v[number.front()].cup[0]==target)||(v[number.front()].cup[1]==target)||(v[number.front()].cup[2]==target))
        {
            cout<<"最少需要"<<v[number.front()].depth<<"步:";
            progress(v[number.front()].last);
            printf("(%d,%d,%d)",v[number.front()].cup[0],v[number.front()].cup[1],v[number.front()].cup[2]);
            cout<<endl;
            return;
        }
        for (int out=0; out<3; out++)
        {
            for (int in=0; in<3; in++)
            {
                if (in==out)
                    continue;
                int num=min(v[number.front()].cup[out],i_cup[in]-v[number.front()].cup[in]);
                if (!num)
                    continue;
                node tem=v[number.front()];
                tem.cup[in]=v[number.front()].cup[in]+num;
                tem.cup[out]=v[number.front()].cup[out]-num;
                if (!vis[tem.cup[1]][tem.cup[2]])
                {
                    vis[tem.cup[1]][tem.cup[2]]=1;
                    v[++k]=tem;
                    v[k].last=number.front();
                    v[k].depth=v[number.front()].depth+1;
                    number.push(k);
                }
            }
        }
        number.pop();
    }
    cout<<"No"<<endl;
}

int main()
{
    int T;
    cin>>T;
    while (T--) {
        memset(vis, 0, sizeof(vis));
        cin>>i_cup[0]>>i_cup[1]>>i_cup[2]>>target;
        bfs();
    }
}
 

 

posted @ 2017-11-18 15:29  soildom  阅读(2912)  评论(0编辑  收藏  举报