POJ 3414 Pots(bfs打印路径)

题意:给定两个空桶的容量分别为A、B,经过6种操作使获得C升水,求最少操作数;

思路:广搜。最少操作数很简单,练习一下打印路径;打印最短路劲就是每次记录当前状态和上一步,找到终点后查找路径。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int A,B,C;
int shortest[150][150];//更新最短步数
int quan[510][510];//记录当前操作
int vis[150][150];//标记
int route[500010],num;//最短路径上的操作,及最少操作数
struct node
{
    int x,y;
    node(){}
    node(int x,int y)
    {
        this->x=x;
        this->y=y;
    }
}q[500010];
node pre[500][500];//上一个操作
int bfs()
{
    int b=0,e=0;
    q[e++]=node(0,0);
    vis[0][0]=1;
    shortest[0][0]=1;
    while(b<e)
    {
        node now=q[b++];
        for(int i=0;i<6;i++)
        {
            int xx,yy;
            if(i==0)//装满1
            {
                xx=A;yy=now.y;
                if(vis[xx][yy]==1) continue;
                vis[xx][yy]=1;
                shortest[xx][yy]=shortest[now.x][now.y]+1;
                q[e++]=node(xx,yy);
                quan[xx][yy]=i;//记录当前操作
                pre[xx][yy]=now;//记录上一步
            }
            if(i==1)//装满2
            {
                yy=B;xx=now.x;
                if(vis[xx][yy]==1) continue;
                vis[xx][yy]=1;
                shortest[xx][yy]=shortest[now.x][now.y]+1;
                q[e++]=node(xx,yy);
                quan[xx][yy]=i;
                pre[xx][yy]=now;
            }
            if(i==2)//清空1
            {
                xx=0;yy=now.y;
                if(vis[xx][yy]==1) continue;
                vis[xx][yy]=1;
                shortest[xx][yy]=shortest[now.x][now.y]+1;
                q[e++]=node(xx,yy);
                quan[xx][yy]=i;
                pre[xx][yy]=now;
            }
            if(i==3)//清空2
            {
                yy=0;xx=now.x;
                if(vis[xx][yy]==1) continue;
                vis[xx][yy]=1;
                shortest[xx][yy]=shortest[now.x][now.y]+1;
                q[e++]=node(xx,yy);
                quan[xx][yy]=i;
                pre[xx][yy]=now;
            }
            if(i==4)//1倒入2
            {
                if(now.x>=B-now.y)
                {
                    yy=B;xx=now.x-(B-now.y);
                }
                else
                {
                    yy=now.y+now.x;xx=0;
                }
                if(vis[xx][yy]==1) continue;
                vis[xx][yy]=1;
                shortest[xx][yy]=shortest[now.x][now.y]+1;
                q[e++]=node(xx,yy);
                quan[xx][yy]=i;
                pre[xx][yy]=now;
            }
            if(i==5)//2倒入1
            {
                if(now.y>=A-now.x)
                {
                    xx=A;yy=now.y-(A-now.x);
                }
                else
                {
                    xx=now.x+now.y;yy=0;
                }
                if(vis[xx][yy]==1) continue;
                vis[xx][yy]=1;
                shortest[xx][yy]=shortest[now.x][now.y]+1;
                q[e++]=node(xx,yy);
                quan[xx][yy]=i;
                pre[xx][yy]=now;
            }
            if(xx==C||yy==C)
            {
                int a,b;
                while(xx!=0||yy!=0)//查找路径
                {
                    route[num++]=quan[xx][yy];
                    a=pre[xx][yy].x;
                    b=pre[xx][yy].y;
                    xx=a;yy=b;
                }
                return shortest[now.x][now.y];
            }
        }
    }
    return -1;
}
int main()
{
    int i,j,k,cnt;
    while(scanf("%d%d%d",&A,&B,&C)!=EOF)
    {
        memset(pre,0,sizeof(pre));
        memset(quan,0,sizeof(quan));
        memset(vis,0,sizeof(vis));
        memset(route,0,sizeof(route));
        memset(shortest,0,sizeof(shortest));
        num=0;temp=INF;
        cnt=bfs();
        if(cnt==-1) printf("impossible\n");
        else
        {
           printf("%d\n",cnt);
           for(i=num-1;i>=0;i--)
           {
               if(route[i]==0)
               {
                   printf("FILL(1)\n");
               }
               else if(route[i]==1)
               {
                   printf("FILL(2)\n");
               }
               else if(route[i]==2)
               {
                   printf("DROP(1)\n");
               }
               else if(route[i]==3)
               {
                   printf("DROP(2)\n");
               }
               else if(route[i]==4)
               {
                   printf("POUR(1,2)\n");
               }
               else if(route[i]==5)
               {
                   printf("POUR(2,1)\n");
               }
           }
        }
    }
    return 0;
}

 

posted on 2015-04-18 13:44  大树置林  阅读(179)  评论(0编辑  收藏  举报

导航