• Jugs(罐子)


    题目大意:给出两个空杯子,已知这两个空杯子的容量,有无限多的水,再给出要求得到的体积,找出一种方法,得到要求的体积

    解决:BFS+路径记录

    #include <iostream>
    #include <cstdio>
    #include <queue>
    using namespace std;
    int ca,cb,n,ex,ey;
    //有六种选择方案,记录的时候只需要记录下,方案的代号0-6即可
    char p[6][20]={"fill A","fill B","pour B A","pour A B","empty A","empty B"};
    //bfs离不开判断是否走过,否则会陷入死循环
    bool vis[1000][1000];
    struct node
    {
        int x,y;
        node(){}
        node(int xx,int yy):x(xx),y(yy){}
    };
    struct pos
    {
        int x,y;
        int kind;
        pos(){}
        pos(int xx,int yy,int k):x(xx),y(yy),kind(k){}
    };
    //存储路径的数组,路径中存放该结点是从哪个结点扩展而来的
    pos path[1000][1000];
    
    void bfs()
    {
        queue<node> q;
        q.push(node(0,0));
        vis[0][0]=1;
        node now;
        path[0][0]=pos(-1,-1,0);
        while(!q.empty())
        {
            now=q.front();
            if(now.x==n ||now.y==n)return;
           q.pop();
            if(!vis[ca][now.y])
            {//fill A的情况,不一定A为空才能fill A
                vis[ca][now.y]=1;
                q.push(node(ca,now.y));
                path[ca][now.y]=pos(now.x,now.y,0); 
                if(ca==n){ ex=ca; ey=0; return; }
            }
            if(!vis[now.x][cb])
            {
                vis[now.x][cb]=1;
                q.push(node(now.x,cb));
                path[now.x][cb]=pos(now.x,now.y,1); 
                if(cb==n){ ex=0; ey=cb; return; }
            }
            if(now.x!=ca && now.y!=0 )
            {//pour B A的情况,这要分两种状态,一种是将A倒满,一种是将B倒空
                
                if(now.x+now.y >= ca && !vis[ca][now.x+now.y-ca])
                {
                    vis[ca][now.x+now.y-ca]=1;
                    q.push(node(ca,now.x+now.y-ca));
                    path[ca][now.x+now.y-ca]=pos(now.x,now.y,2);
                    if(now.x+now.y-ca==n){ ex=ca; ey=now.x+now.y-ca;  return;}
                }
                else if(now.x + now.y < ca && !vis[now.x+now.y][0])
                {
                    vis[now.x+now.y][0]=1;
                    q.push(node(now.x+now.y,0));
                    path[now.x+now.y][0]=pos(now.x,now.y,2);
                    if(now.x+now.y==n){ ex=now.x+now.y; ey=0; return;}
                }
            }
            if(now.y!=cb && now.x!=0)
            {//pour A B的情况,一种是将B倒满,一种是将A倒空
                if(now.x+now.y >= cb && !vis[now.x+now.y-cb][cb])
                {
                    vis[now.x+now.y-cb][cb]=1;
                    q.push(node(now.x+now.y-cb,cb));
                    path[now.x+now.y-cb][cb]=pos(now.x,now.y,3);
                    if(now.x+now.y-cb==n){ ex=now.x+now.y-cb; ey=cb; return;}
                }
                else if(now.x + now.y < cb && !vis[0][now.x+now.y])
                {
                    vis[0][now.x+now.y]=1;
                    q.push(node(0,now.x+now.y));
                    path[0][now.x+now.y]=pos(now.x,now.y,3);
                    if(now.x+now.y==n){ now.x=0; now.y=now.x+now.y; return;}
                }
            }
            if(!vis[0][now.y])
            {//empty A的情况,不一定A满了才能倒空
                vis[0][now.y]=1;
                q.push(node(0,now.y));
                path[0][now.y]=pos(now.x,now.y,4);
            }
            if(!vis[now.x][0])
            {//empty B的情况,不一定B满了才能倒空
                vis[now.x][0]=1;
                q.push(node(now.x,0));
                path[now.x][0]=pos(now.x,now.y,5);
            }
        }
    }
    void print(int x,int y)
    {
        if(path[x][y].x!=-1 && path[x][y].y!=-1)
        {
            print(path[x][y].x,path[x][y].y);
            printf("%s\n",p[path[x][y].kind]);
        }
    }
    int main()
    {
      
        while(cin>>ca>>cb>>n)
        {
            memset(vis,0,sizeof(vis));
            bfs();
            print(ex,ey);    
            cout<<"success"<<endl;    
        }
        system("pause");
        return 0;
    }
    

    poj 3414和此题一模一样,但是下边代码,提供一种不同的记录路径的方式,用string来记录,从起始到当前扩展结点的所有路

    经,而不是仅仅记录该结点是由哪个结点扩展来的。

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <string>
    using namespace std;
    int ca,cb,n,ex,ey;
    char p[6][20]={"FILL(1)","FILL(2)","POUR(2,1)","POUR(1,2)","DROP(1)","DROP(2)"};
    bool vis[105][105];
    struct node
    {
        int x,y;
        int step;
       //string 方法记录路径
        string way;
        node(){}
        node(int xx,int yy,int s,string w):x(xx),y(yy),step(s),way(w){}
    };
    string res;
    /*
    struct pos
    {
        int x,y;
        int kind;
        pos(){}
        pos(int xx,int yy,int k):x(xx),y(yy),kind(k){}
    };
    pos path[105][105];
    */
    int bfs()
    {
        queue<node> q;
        q.push(node(0,0,0,""));
        vis[0][0]=1;
        node now;
        while(!q.empty())
        {
            now=q.front();
            if(now.x==n ||now.y==n){res=now.way; return now.step;}
            q.pop();
            if(!vis[ca][now.y])
            {
                vis[ca][now.y]=1;
                q.push(node(ca,now.y,now.step+1,now.way+"0"));
                if(ca==n){
                res=q.back().way;
                return now.step+1;
                }
            }
            if(!vis[now.x][cb])
            {
                vis[now.x][cb]=1;
                q.push(node(now.x,cb,now.step+1,now.way+"1"));
                if(cb==n){
                res=q.back().way;
                return now.step+1; 
               }
            }
            if(now.x!=ca && now.y!=0 )
            {
                
                if(now.x+now.y >= ca && !vis[ca][now.x+now.y-ca])
                {
                    vis[ca][now.x+now.y-ca]=1;
                    q.push(node(ca,now.x+now.y-ca,now.step+1,now.way+"2"));
                    if(now.x+now.y-ca==n){ 
                    res=q.back().way;
                    return now.step+1;
                    }
                }
                else if(now.x + now.y < ca && !vis[now.x+now.y][0])
                {
                    vis[now.x+now.y][0]=1;
                    q.push(node(now.x+now.y,0,now.step+1,now.way+"2"));
                    if(now.x+now.y==n){ 
                    res=q.back().way;
                    return now.step+1;
                    }
                }
            }
            if(now.y!=cb && now.x!=0)
            {
                if(now.x+now.y >= cb && !vis[now.x+now.y-cb][cb])
                {
                    vis[now.x+now.y-cb][cb]=1;
                    q.push(node(now.x+now.y-cb,cb,now.step+1,now.way+"3"));
                    if(now.x+now.y-cb==n){
                     res=q.back().way;
                     return now.step+1;
                     }
                }
                else if(now.x + now.y < cb && !vis[0][now.x+now.y])
                {
                    vis[0][now.x+now.y]=1;
                    q.push(node(0,now.x+now.y,now.step+1,now.way+"3"));
                    if(now.x+now.y==n){ 
                     res=q.back().way;
                     return now.step+1;
                     }
                }
            }
            if(!vis[0][now.y])
            {
                vis[0][now.y]=1;
                q.push(node(0,now.y,now.step+1,now.way+"4"));
            }
            if(!vis[now.x][0])
            {
                vis[now.x][0]=1;
                q.push(node(now.x,0,now.step+1,now.way+"5"));
            }
        }
        return -1;
    }
    
    int main()
    {
      
        cin>>ca>>cb>>n;
        memset(vis,0,sizeof(vis));
        int t=bfs();
        if(t >=0 )
        {
            cout<<t<<endl; 
            int n=res.size();
            for(int i=0;i<n;i++)
                puts(p[res[i]-'0']);
        }
          else cout<<"impossible"<<endl;
        system("pause");
        return 0;
    }
    

  • 相关阅读:
    112th LeetCode Weekly Contest Validate Stack Sequences
    112th LeetCode Weekly Contest Minimum Increment to Make Array Unique
    C# 有关系统音量的操作
    C# 关于时区的操作
    WordPress 设置GeoIP数据库目录权限时错误解决方案
    AtCoder Beginner Contest 113 C
    AtCoder Beginner Contest 113 B
    AtCoder Beginner Contest 113 A
    将Tomcat注册为Windows服务
    常用的调试方法
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2174995.html
Copyright © 2020-2023  润新知