倒水(BFS)Pots POJ - 3414

Pots POJ - 3414

题目链接

bfs题;
标注的状态应为2容器的体积,因为每种2容器的体积都应该只由一种状态达到。

不使用队列

#include<stdio.h>
#include<string.h>
struct node{
int now_x;
int now_y;
int step;
int howcome;
int before;
}ll[10050];
int head=1,tail=1,c[150000],cnt=0,vis[150][150];
int x,y,z;
void bfs()
{
    int lx,ly;
    while(head<=tail)
    {
        lx=ll[head].now_x;
        ly=ll[head].now_y;
 //       printf("%d %d %d %d %d\n",head,tail,ll[head].step,lx,ly);
        if(lx==z||ly==z)
        {
            printf("%d\n",ll[head].step);
    //        printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
            int w=head;
            while(1)
            {
                c[cnt]=ll[w].howcome;
                cnt++;
            //    printf("%d\n",ll[w].howcome);
                w=ll[w].before;
                if(w==1)
                    break;
            }
            for(int k=cnt-1;k>=0;k--)
            {
                if(c[k]==3)
                    printf("FILL(1)\n");
                if(c[k]==4)
                    printf("FILL(2)\n");
                if(c[k]==1)
                    printf("DROP(1)\n");
                if(c[k]==2)
                    printf("DROP(2)\n");
                if(c[k]==5)
                    printf("POUR(1,2)\n");
                if(c[k]==6)
                    printf("POUR(2,1)\n");
            }
            return ;
        }
        if(lx>0&&vis[0][ly]==0)    //倒x的水。
        {
            tail++;
            ll[tail].now_x=0;
            ll[tail].now_y=ly;
            int llx=ll[tail].now_x;
            int lly=ll[tail].now_y;
            vis[llx][lly]=1;
            ll[tail].step=ll[head].step+1;
            ll[tail].howcome=1;
            ll[tail].before=head;
       /*     if(ll[tail].now_x==z||ll[tail].now_y==z)
            {
                printf("%d\n",ll[tail].step);
            }*/
        }
        if(ly>0&&vis[lx][0]==0)    //倒y的水。
        {
            tail++;
            ll[tail].now_x=lx;
            ll[tail].now_y=0;
            int llx=ll[tail].now_x;
            int lly=ll[tail].now_y;
            vis[llx][lly]=1;
            ll[tail].step=ll[head].step+1;
            ll[tail].howcome=2;
            ll[tail].before=head;
          /*  if(ll[tail].now_x==z||ll[tail].now_y==z)
            {
                printf("%d\n",ll[tail].step);
            }*/
        }
        if(lx<x&&vis[x][ly]==0)    //把x的水装满。
        {
            tail++;
            ll[tail].now_x=x;
            ll[tail].now_y=ly;
            int llx=ll[tail].now_x;
            int lly=ll[tail].now_y;
            vis[llx][lly]=1;
            ll[tail].step=ll[head].step+1;
            ll[tail].howcome=3;
            ll[tail].before=head;
        /*    if(ll[tail].now_x==z||ll[tail].now_y==z)
            {
                printf("%d\n",ll[tail].step);
            }*/
        }
        if(ly<y&&vis[lx][y]==0)    //把y的水装满。
        {
            tail++;
            ll[tail].now_x=lx;
            ll[tail].now_y=y;
            int llx=ll[tail].now_x;
            int lly=ll[tail].now_y;
            vis[llx][lly]=1;
            ll[tail].step=ll[head].step+1;
            ll[tail].howcome=4;
            ll[tail].before=head;
       /*     if(ll[tail].now_x==z||ll[tail].now_y==z)
            {
                printf("%d\n",ll[tail].step);
            }*/
        }
        if(lx>0&&ly<y)        //把x的水倒入y中。
        {
            int oy1=lx+ly-y;
            int oy2=lx+ly;
            if(lx+ly>y&&vis[oy1][y]==0)
            {
                tail++;
                ll[tail].now_x=lx+ly-y;
                ll[tail].now_y=y;
                int llx=ll[tail].now_x;
                int lly=ll[tail].now_y;
                vis[llx][lly]=1;
                ll[tail].step=ll[head].step+1;
                ll[tail].howcome=5;
                ll[tail].before=head;
            }
            if(lx+ly<=y&&vis[0][oy2]==0)
            {
                tail++;
                ll[tail].now_x=0;
                ll[tail].now_y=lx+ly;
                int llx=ll[tail].now_x;
                int lly=ll[tail].now_y;
                vis[llx][lly]=1;
                ll[tail].step=ll[head].step+1;
                ll[tail].howcome=5;
                ll[tail].before=head;
            }
        }
        if(ly>0&&lx<x)        //把y的水倒入x中。
        {

            int ox1=lx+ly-x;
            int ox2=lx+ly;
            if(lx+ly>x&&vis[x][ox1]==0)
            {
                tail++;
                ll[tail].now_x=x;
                ll[tail].now_y=lx+ly-x;
                int llx=ll[tail].now_x;
                int lly=ll[tail].now_y;
                vis[llx][lly]=1;
                ll[tail].step=ll[head].step+1;
                ll[tail].howcome=6;
                ll[tail].before=head;
            }
            if(lx+ly<=x&&vis[ox2][0]==0)
            {
                tail++;
                ll[tail].now_x=lx+ly;
                ll[tail].now_y=0;
                int llx=ll[tail].now_x;
                int lly=ll[tail].now_y;
                vis[llx][lly]=1;
                ll[tail].step=ll[head].step+1;
                ll[tail].howcome=6;
                ll[tail].before=head;
            }
        }
        head++;
    }
    printf("impossible\n");
    return ;
}
int main()
{
    scanf("%d%d%d",&x,&y,&z);
    memset(vis,0,sizeof(vis));
    ll[1].now_x=0;
    ll[1].now_y=0;

    ll[1].step=0;
    bfs();
    return 0;
}

使用队列;

# include<stdio.h>
# include <queue>
# include <string.h>
using namespace std;

# define max 110
int A,B,C;
char num[12][12] = {"FILL(1)","FILL(2)", "DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
struct node
{
    int x,y,step,op;//OP是用来最后作为num数组的下标指引路径 
}v[max][max];

struct point
{
    int x, y;
};

void DFS(int x, int y)//用递归来返回路径 
{
    if(x == 0 && y == 0)
    return;
    DFS(v[x][y].x, v[x][y].y);
    printf("%s\n",num[ v[x][y].op ]);
}

int BFS( point t )
{   
    queue<point>Q;
    v[0][0].step = 1;
    Q.push(t);  

    while(Q.size())
    {
        point s = Q.front();
        Q.pop();

        if(s.x == C || s.y == C)
        {
            printf("%d\n", v[s.x][s.y].step-1);
            DFS(s.x, s.y);
            return 0;   
        }

        for(int i = 0; i<6; i++)
        {
            point q = s;    
            if(i == 0)
            {
                q.x = A;
            }
            else if(i == 1)
            {
                q.y = B;
            }
            else if(i == 2)
            {

                q.x = 0;
            }
            else if( i== 3)
            {
                q.y = 0;
            }
         else if(i == 4)
            {
                if(q.x+q.y <= B)
                    q.y += q.x, q.x = 0;//把A里面的水全倒B里面
                else
                    q.x -= (B-q.y), q.y = B;//把B倒满
            }
            else
            {
                if(q.x+q.y <= A)
                    q.x += q.y, q.y = 0;
                else
                    q.y -= (A-q.x), q.x = A;
            }
            if( v[q.x][q.y].step == 0)//用当下当成下标,将以前当成值 
            {
                v[q.x][q.y].step = v[s.x][s.y].step +1;
                v[q.x][q.y].x = s.x;
                v[q.x][q.y].y = s.y;
                v[q.x][q.y].op = i;//路径下标指引所以上面0-5的操作要和路径数组里要求的一致 
                Q.push(q);
            }           
        }       
    }
    return -1;  
}
int main(void)
{
    while(~scanf("%d%d%d",&A,&B,&C))
    {
        memset(v, 0, sizeof(v));
        point s;
        s.x = 0;
        s.y = 0;
        int ans = BFS(s);
        if(ans == -1)
          printf("impossible\n");               
    }   
    return 0;
} 

发布了18 篇原创文章 · 获赞 7 · 访问量 999

猜你喜欢

转载自blog.csdn.net/qq_43559193/article/details/88709182
今日推荐