Pots(POJ 3414)——BFS

题目链接:http://poj.org/problem?id=3414
题目大意:有A,B容量的两个杯子,然后有六种操作,分别是:

"FILL(1)";//将杯子1装满
"FILL(2)";//将杯子2装满
"DROP(1)";//将杯子1中的水全部倒掉
"DROP(2)";//将杯子2中的水全部倒掉
"POUR(1,2)";//将杯子1中的水倒入2中
"POUR(2,1)";//将杯子2中的水倒入1中
(倾倒水的时候如果能倒完就倒完,如果倒不完,就剩在原来杯子里)

问:是否有一系列操作使得任意一个杯子中出现水量为C的水。

题解:
首先想到用BFS嘛,每种状态可向下继续走的有六种操作。如果没有操作的记录的话就没那么麻烦,就直接常规的做就好了。但是有了要记录操作的记录,所以我们要处理一下这个嘛。
主要就是将所有放入队列的结构体编号,然后记录下当前编号和上一步操作的编号以便于我们最后的输出。然后就做就好了。
还有一个就是map输出要用cout,第一次用map,其实也不必要用map的,但是因为刚接触了然后就想试试,然后就用了。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <math.h>
#include <string.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>

#define INF 0x3f3f3f3f
const int MAX=0x3f3f3f3f;

using namespace std;
typedef long long ll;
map<int,string> path;
int A,B,C;

struct node{
    int x,y;//当前水量;
    int op;//具体的操作
    int s;//路径长度
    int now;//当前的编号
    int pre;//前一个步骤的编号
}tt[1000];//用来存所有放入过队列的结构体编号
int flag=0;
int id[1000];//用来存最优系列操作的编号
int endid;//用来记录最后一个操作的编号
int mp[1000][1000];//看这个状态是否走过
int bfs(int ex,int ey)
{
    memset(mp,false,sizeof(mp));
    tt[0].x=ex;
    tt[0].y=ey;
    tt[0].s=0;
    tt[0].now=0;
    tt[0].pre=0;
    queue<node>q;
    q.push(tt[0]);
    mp[q.front().x][q.front().y]=1;
    flag++;
    while(!q.empty())
    {
        node temp;
        for(int i=1;i<=6;i++)
        {
            switch (i) {
                case 1://将第一个杯子装满
                {
                    temp.x = A;
                    temp.y = q.front().y;
                    goto loop;
                }
                case 2://将第二个杯子装满
                {
                    temp.y = B;
                    temp.x = q.front().x;
                    goto loop;
                }
                case 3://将第一个杯子清空
                {
                    temp.x = 0;
                    temp.y = q.front().y;
                    goto loop;
                }
                case 4://将第二个杯子清空
                {
                    temp.y = 0;
                    temp.x = q.front().x;
                    goto loop;
                }
                case 5://将第一个杯子的水倒入第二个杯子
                {
                    //如果可以把第二个杯子倒满
                    if (q.front().x >= (B - q.front().y)) {
                        temp.x = q.front().x - (B - q.front().y);
                        temp.y = B;
                    }
                    //如果不能把第二个杯子倒满
                    if (q.front().x < (B - q.front().y)) {
                        temp.y = q.front().y + q.front().x;
                        temp.x = 0;
                    }
                    goto loop;
                }
                case 6://将第二个杯子的水倒入第一个杯子
                {
                    //如果可以把第一个杯子倒满
                    if (q.front().y >= (A - q.front().x)) {
                        temp.y = q.front().y - (A - q.front().x);
                        temp.x = A;
                    }
                    //如果不能把第二个杯子倒满
                    if (q.front().y < (A - q.front().x)) {
                        temp.x = q.front().y + q.front().x;
                        temp.y = 0;
                    }
                    goto loop;
                }
            }
            loop:
            if(mp[temp.x][temp.y]==1)
                continue;
            temp.op=i;
            temp.s=q.front().s+1;
            temp.now=flag;
            temp.pre=q.front().now;
            q.push(temp);
            tt[flag]=temp;
            flag++;
            mp[temp.x][temp.y]=1;
            if(temp.x==C||temp.y==C)
            {
                endid=temp.now;
                return temp.s;
            }
        }
        q.pop();
    }
    return 0;
}
int main()
{
    path[1]="FILL(1)";
    path[2]="FILL(2)";
    path[3]="DROP(1)";
    path[4]="DROP(2)";
    path[5]="POUR(1,2)";
    path[6]="POUR(2,1)";
    while(~scanf("%d%d%d",&A,&B,&C))
    {
        int ans=bfs(0,0);
        if(ans==0)
            printf("impossible\n");
        else
        {
            printf("%d\n",ans);
            id[ans]=endid;
            for(int i=ans-1;i>=1;i--)
            {
                id[i]=tt[id[i+1]].pre;
            }
            for(int i=1;i<=ans;i++)
            {
                cout<<path[tt[id[i]].op]<<endl;
            }
        }
    }
    return 0;
}

(一个月了,首发题,寒假懒死了……想哭)

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/87951069
今日推荐