POJ3414 Pots BFS

题目大意:给出两个容量分别为V1,V2的瓶子,和目标水量C,瓶子可以进行如下3种操作:

(1)FILL( i ):将第i个瓶子装满水(i=1,2);

(2)DROP( i ):将第i个瓶子里的水全部到出(i=1,2);

(3)POUR( i,j):将第i个瓶子的水倒入第j个瓶子中(或将i中的水全部倒入j中,或将i中的一部分水倒入j中的时候j已经装满)。

现在问你经过多少次操作能使其中一个瓶子出现目标水量。如果不能实现,输出“impossible”。



分析过程链接



实现代码如下:

#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstring>
#include <string>
#include <map>
using namespace std;
int v1,v2;
int c;
int k1,k2;
int cmp1=0,cmp2=0;
int op[1000];
map <string,bool> vis;
typedef struct nod
{
    int x,y;
    int pos;
    int step;
}node;
node que[1000];
string comb(int a,int b)
{
    string s;
    ostringstream os;
    os<<a<<","<<b;
    s=os.str();
    os.str("");
    return s;
}

void fill(int n,node cnt)
{
    k1=cnt.x;
    k2=cnt.y;
    if(n==1) k1=v1;
    else k2=v2;
    string ts=comb(k1,k2);
    if(!vis[ts])
    {
        vis[ts]=1;
        que[cmp2].x=k1;
        que[cmp2].y=k2;
        que[cmp2].step=cnt.step+1;
        que[cmp2].pos=cmp1;
        if(n==1) op[cmp2++]=210;
        else op[cmp2++]=220;
    }
}

void drop(int n,node cnt)
{
    k1=cnt.x;
    k2=cnt.y;
    if(n==1) k1=0;
    else k2=0;
    string ts=comb(k1,k2);
    if(!vis[ts])
    {
        vis[ts]=1;
        que[cmp2].x=k1;
        que[cmp2].y=k2;
        que[cmp2].step=cnt.step+1;
        que[cmp2].pos=cmp1;
        if(n==1) op[cmp2++]=110;
        else op[cmp2++]=120;
    }
}

void pour(int n,node cnt)
{
    k1=cnt.x;
    k2=cnt.y;
    if(n==1)
    {
        if(k1+k2<=v2) { k2=k1+k2;k1=0; }
        else { k1=k1+k2-v2; k2=v2; }
    }
    else
    {
        if(k1+k2<=v1) { k1=k1+k2; k2=0;  }
        else { k2=k1+k2-v1;  k1=v1; }
    }
    string ts=comb(k1,k2);
    if(!vis[ts])
    {
        vis[ts]=1;
        que[cmp2].x=k1;
        que[cmp2].y=k2;
        que[cmp2].step=cnt.step+1;
        que[cmp2].pos=cmp1;
        if(n==1) op[cmp2++]=312;
        else op[cmp2++]=321;
    }
}

void bfs()
{
    memset(op,0,sizeof(op));
    vis.clear();
    cmp1=0;cmp2=0;
    que[cmp2].x=0;
    que[cmp2].y=0;
    que[cmp2++].step=0;
    vis["0,0"]=1;
    while(cmp1<cmp2)
    {
        node cnt=que[cmp1];
        if(cnt.x==c||cnt.y==c)
        {
            printf("%d\n",cnt.step);
            int cs=cnt.step;
            int *steps=new int[cs+1];
            steps[cs--]=cmp2-1;
            while(cs)
            {
                steps[cs]=que[ steps[cs+1] ].pos;
                cs--;
            }
            for(int i=1;i<=cnt.step;i++)
            {
                int tmp=op[ steps[i]-1 ];
                switch(tmp/100)
                {
                    case 1:printf("DROP(%d)\n",(tmp/10)%10);break;
                    case 2:printf("FILL(%d)\n",(tmp/10)%10);break;
                    case 3:printf("POUR(%d,%d)\n",(tmp/10)%10,tmp%10);
                }
            }
            delete steps;
            return ;
        }
        fill(1,cnt);  fill(2,cnt);
        drop(1,cnt);  drop(2,cnt);
        pour(1,cnt);  pour(2,cnt);

    cmp1++;
    }
    puts("impossible");
    return ;
}
int main()
{
    while(scanf("%d%d%d",&v1,&v2,&c)!=-1)
      bfs();
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值