Pot——bfs

给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作

FILL(i)        将第i个容器从水龙头里装满(1 ≤ i ≤ 2);

DROP(i)        将第i个容器抽干

POUR(i,j)      将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)

现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程

Input

有且只有一行,包含3个数A,B,C(1<=A,B<=100,C<=max(A,B))

Output

第一行包含一个数表示最小操作数K

随后K行每行给出一次具体操作,如果有多种答案符合最小操作数,输出他们中的任意一种操作过程,如果你不能使两个容器中的任意一个满足恰好C升的话,输出“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、1倒到2里面

2、2倒到1里面

3、 1倒空

4、 2倒空

5、 1填满

6、 2填满

把抽象的生活问题数学化,也就是以什么为度量的单位?

开始是0 0 , 后来进行操作,这两个数会进行改变,直到有一个数到达指定的值得时候输出,如果说遍历一遍都不成立,那么就说明没有正确答案,输出impossible。

那么怎么进行度量呢?首先上面的六个步骤在每次输出的时候结果是一样的,那么是否就可以考虑把六种情况放到数组里面呢?答案是肯定的,放到数组里面后,只需要输入相应的下标,就可以输出对应的字符串,那么问题也就简化成了求每次的下标了。

六个步骤前面的序号暂且认为是下标,那么在进行相应的操作的时候就需要一个数组来记录这个下标。

下标找到以后就是输出了,那么问题也就来了,该怎么输出呢?

前面有说,其中的一个难点是回溯,解决的问题就是输入函数的下标是n-1,怎么才能变成1输出。

lastopr数组如果是某一项的下标,那么lastx,lasty再进入函数后前一项的下标。

代码如下:

#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
int index[105][105];
int lastopr[105][105];
int lastx[105][105];
int lasty[105][105];
char oper[][10]= {"","POUR(1,2)","POUR(2,1)","DROP(1)","DROP(2)","FILL(1)","FILL(2)"};
int a,b,c;
struct xiao
{
    int x,y,step;
};

void dfs(int xxx,int yyy)
{
   if(lastopr[xxx][yyy]!=0)
   {
       dfs(lastx[xxx][yyy],lasty[xxx][yyy]);

       printf("%s\n",oper[lastopr[xxx][yyy]]);
   }
   return ;
}
void bfs()
{
    queue<xiao>q;
    memset(index,0,sizeof(index));
    xiao e;
    e.x=0;
    e.y=0;
    e.step=0;
    index[e.x][e.y]=1;
    lastopr[0][0]=0;
    q.push(e);
    while(!q.empty())
    {
        xiao s;
        s=q.front();
        q.pop();
        if(s.x==c||s.y==c)
        {
            printf("%d\n",s.step);
            dfs(s.x,s.y);
            return ;
        }
        if(s.x!=0)
        {
            if(s.x>b-s.y)
            {
                e.x=s.x-(b-s.y);
                e.y=b;
                e.step=s.step+1;
            }
            else
            {
                e.x=0;
                e.y=s.x+s.y;
                e.step=s.step+1;
            }
            if(index[e.x][e.y]==0)
            {
                index[e.x][e.y]=1;
                lastopr[e.x][e.y]=1,lastx[e.x][e.y]=s.x,lasty[e.x][e.y]=s.y;
                q.push(e);
            }

        }
        if(s.y!=0)//从2到1
        {
            if(s.y>a-s.x)
            {
                e.y=s.y-(a-s.x);
                e.x=a;
                e.step=s.step+1;
            }
            else
            {
                e.y=0;
                e.x=s.y+s.x;
                e.step=s.step+1;
            }
            if(index[e.x][e.y]==0)
            {
                index[e.x][e.y]=1;
                lastopr[e.x][e.y]=2,lastx[e.x][e.y]=s.x,lasty[e.x][e.y]=s.y;
                q.push(e);
            }
        }
        if(s.x!=0)//a中的倒出
        {
            e.x=0;
            e.y=s.y;
            e.step=s.step+1;
            if(index[e.x][e.y]==0)
            {
                index[e.x][e.y]=1;
                lastopr[e.x][e.y]=3,lastx[e.x][e.y]=s.x,lasty[e.x][e.y]=s.y;
                q.push(e);
            }
        }
        if(s.y!=0)//b中的倒出
        {
            e.y=0;
            e.x=s.x;
            e.step=s.step+1;
            if(index[e.x][e.y]==0)
            {
                index[e.x][e.y]=1;
                q.push(e);
                lastopr[e.x][e.y]=4,lastx[e.x][e.y]=s.x,lasty[e.x][e.y]=s.y;
            }
        }

        if(s.x!=a)//a倒满
        {
            e.x=a;
            e.y=s.y;
            e.step=s.step+1;
            if(index[e.x][e.y]==0)
            {
                index[e.x][e.y]=1;
                q.push(e);
                lastopr[e.x][e.y]=5,lastx[e.x][e.y]=s.x,lasty[e.x][e.y]=s.y;
            }
        }
        if(s.y!=b)//b倒满
        {
            e.y=b;
            e.x=s.x;
            e.step=s.step+1;
            if(index[e.x][e.y]==0)
            {
                index[e.x][e.y]=1;
                q.push(e);
                lastopr[e.x][e.y]=6,lastx[e.x][e.y]=s.x,lasty[e.x][e.y]=s.y;
            }
        }
    }
    printf("impossible\n");
}

int main()
{
    scanf("%d%d%d",&a,&b,&c);
    bfs();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zbq_tt5/article/details/85299593
BFS