POJ - 3414----Pots

本文介绍了一种通过有限操作步骤实现特定水量调配的算法。利用广度优先搜索(BFS)策略,在不超过两个容器的最大容量限制的情况下,寻找从初始状态到达目标状态的最短路径。该算法适用于解决类似经典水罐问题的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
DROP(i) empty the pot i to the drain;
POUR(i,j) pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).
Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

Input
On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

Output
The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input
3 5 4
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

题目大意:就是给你两个空杯子1,2(有额定容量).你有6中操作。将杯子1加满,将杯子2加满,将杯子1倒空,将杯子2倒空,将1中的水加到2中,将2中的水加到1中(只能全倒或另个杯子满才停止),求出最少的操作步骤使得量出所需的容量。

思路:一个多入口的BFS,不过要记录步骤,就在节点力多添个数组来记录。

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio> 
using namespace std;
const int MAX=1000;

struct node{
    int a,b; //杯子水的状态 
    int step;//记录操作的步数 
    char str[100][100];//记录操作的步骤 
}; 

bool visit[MAX][MAX];//水的访问状态 

int BFS(int a,int b,int c){
    queue<node> Q;

    memset(visit,false,sizeof(visit));
    node t1;

    t1.a = 0;
    t1.b = 0;
    t1.step = 0;
    visit[t1.a][t1.b] = true; 

    Q.push(t1);//初始情况入队 

    while(!Q.empty()){  
        node tem = Q.front();
        Q.pop();

        //找到 
        if(tem.a==c || tem.b==c){
            cout<<tem.step<<endl; 
            for(int i=0 ; i<=tem.step ; i++){
                cout<<tem.str[i]<<endl;
            }
            return 1;
        }

        //6种操作 
        for(int i=1 ; i<=6 ; i++){
            node temp = tem;
            switch(i){
                //将a瓶倒掉 
                case 1:{
                    //a非空才倒 
                    if(temp.a != 0){
                        temp.a = 0;
                        temp.step = tem.step+1;
                        strcpy(temp.str[temp.step],"DROP(1)");
                    }
                    break;
                }
                //将b瓶倒掉 
                case 2:{
                    //b非空才倒 
                    if(temp.b != 0){
                        temp.b = 0;
                        temp.step = tem.step+1;
                        strcpy(temp.str[temp.step],"DROP(2)");
                    }
                    break;
                }

                //将a瓶加满 
                case 3:{
                    //a不满才加 
                    if(temp.a !=a){
                        temp.a = a;
                        temp.step = tem.step+1;
                        strcpy(temp.str[temp.step],"FILL(1)");
                    }
                    break;
                }
                //将b瓶加满 
                case 4:{
                    //b不满才加 
                    if(temp.b != b){
                        temp.b = b;
                        temp.step = tem.step+1;
                        strcpy(temp.str[temp.step],"FILL(2)");
                    }
                    break;
                }
                //a加到b
                case 5:{
                    //a不空b不满时加 
                    if(temp.a!=0 && temp.b!=b){
                        //加够了 
                        if(tem.a + tem.b > b){
                            temp.a -= b-tem.b;
                            temp.b = b;
                        }else{//没加够 
                            temp.a = 0;
                            temp.b += tem.a;;   
                        }
                        temp.step = tem.step+1;
                        strcpy(temp.str[temp.step],"POUR(1,2)");
                    }
                    break;
                }
                //b加到a 
                case 6:{
                    //b不空a不满时加 
                    if(temp.b!=0 && temp.a!=a){
                        //加够了 
                        if(tem.a + tem.b > a){
                            temp.b -= a-tem.a;
                            temp.a = a;
                        }else{//没加够 
                            temp.b = 0;
                            temp.a += tem.b;
                        }
                        temp.step = tem.step+1; 
                        strcpy(temp.str[temp.step],"POUR(2,1)");
                    }
                    break;      
                }
            }
            if(temp.a==c || temp.b==c){
                cout<<temp.step<<endl; 
                for(int i=0 ; i<=temp.step ; i++){
                    cout<<temp.str[i]<<endl;
                }
                return 1;
            }


            //此状态没有访问过 
            if(!visit[temp.a][temp.b]){
                visit[temp.a][temp.b] = true;
                Q.push(temp);
            }
        }
    }
    return 0;
} 
int main(void){
    int a,b,c;

    cin>>a>>b>>c;

    if(BFS(a,b,c)==0){
        cout<<"impossible"<<endl;
    }

    return 0;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值