• 倒水问题(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();
        }
    }
     

  • 相关阅读:
    CF 1292A 迷宫
    JSOI Salesman 树形Dp
    HDU-1051 一个DP问题
    洛谷 P2656 采蘑菇 树形DP+缩点+坑点
    JSOI 2016 病毒感染 辅助Dp问题
    Codeforces D. Color the Fence(贪心)
    Codeforces H. Maximal GCD(贪心)
    Codeforces J. A Simple Task(多棵线段树)
    Codeforces C. A Simple Task(状态压缩dp)
    子集生成的三种算法
  • 原文地址:https://www.cnblogs.com/soildom/p/7856826.html
Copyright © 2020-2023  润新知