POJ 3414-Pots(暑假头疼jixun)

本文详细解析了POJ3414-Pots问题,通过使用BFS搜索算法找到从两个不同容量的水壶中精确倒出指定水量的最短操作序列。代码实现展示了如何通过状态记录避免重复搜索,最终输出操作步骤。

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

POJ 3414-Pots

Description

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)
思路:用bfs进行搜索,建立一个数组记录此时状态,用来确保它不会再次出现这种状态,搜索出一个最短的路径并记录步数与所用的方法;最后全部储存在栈中,最终输出,,(自己表示现在的我有点苍白无力,这种代码,回溯那个阶段还是有点糊,毕竟还是太菜,也只能把现在想法写一写)

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iterator>
#include<vector>
#include<stdlib.h>
#include<map>
#include<queue>
#include<stack>
typedef long long ll;
using namespace std;
int dir[4][2] = {{ -1, 0}, {1, 0}, { 0, -1}, {0, 1}};
struct cup
{
    int x, y;
    int step;
    int flag;
    cup *pre;
};
queue<cup>Q;
stack<int>R;
int a, b, e;
int vis[117][117] = {0};
int ans;
void bfs(int x, int y)
{
    cup c;
    cup t[317];
    c.x = 0;
    c.y = 0;
    c.flag = 0;
    c.pre = NULL;
    c.step = 0;
    Q.push(c);
    vis[x][y] = 1;
    int cot = -1;
    while(!Q.empty())
    {
        cot++;
        t[cot] = Q.front();
        Q.pop();
        for(int i = 1; i <= 6; i++)
        {
            switch(i)
            {
                case 1:
                    c.x = a;//将A装满
                    c.y = t[cot].y;
                    c.flag = 1;
                    break;
                case 2:
                    c.x = t[cot].x;//将B装满
                    c.y = b;
                    c.flag = 2;
                    break;
                case 3:
                    c.x = 0;//将A倒掉
                    c.y = t[cot].y;
                    c.flag = 3;
                    break;
                case 4:
                    c.x = t[cot].x;//将B倒掉
                    c.y = 0;
                    c.flag = 4;
                    break;
                case 5: //将A倒入B
                    if(t[cot].x>b-t[cot].y){
                        c.x = t[cot].x-(b-t[cot].y);
                        c.y = b;
                    }
                    else
                    {
                        c.x = 0;
                        c.y = t[cot].y+t[cot].x;
                    }
                    c.flag = 5;
                    break;
                case 6: //将B倒入A;
                    if(t[cot].y>a-t[cot].x){
                        c.y = t[cot].y-(a-t[cot].x);
                        c.x = a;
                    }
                    else
                    {
                        c.x = t[cot].x+t[cot].y;
                        c.y = 0;
                    }
                    c.flag = 6;
                    break;
            }
            if(vis[c.x][c.y])
                continue;
            vis[c.x][c.y] = 1;
            c.step = t[cot].step+1;
            c.pre = &t[cot];
            if(c.x ==e||c.y==e){
                ans = c.step;
                while(c.pre){//这里是一个回溯的过程
                    R.push(c.flag);//因为R是栈,所以后进先出
                    c = *c.pre;//这里应该传递的是上一个c的地址
                }
                return;
            }
            Q.push(c);
        }
    }
}
void print()
{
    while(!R.empty()){
        int i = R.top();
        R.pop();
        switch(i)
        {
            case 1:cout<<"FILL(1)"<<endl;break;
            case 2:cout<<"FILL(2)"<<endl;break;
            case 3:cout<<"DROP(1)"<<endl;break;
            case 4:cout<<"DROP(2)"<<endl;break;
            case 5:cout<<"POUR(1,2)"<<endl;break;
            case 6:cout<<"POUR(2,1)"<<endl;break;
        }
    }
}
int main()
{
    cin >> a >> b >> e;
    bfs(0, 0);
    if(ans == 0)
    {
        cout << "impossible" << endl;
    }
    else
    {
        cout << ans << endl;
        print();
    }
    return 0;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值