zoukankan      html  css  js  c++  java
  • POJ 3414 Pots

    bfs优先队列,把操作名称存入对应的下标,分六种情况讨论入队。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <vector>
    using namespace std;
    const int N = 110;
    int vis[N][N];
    int point[N*N];
    char option[][10] = {"#","FILL(1)","FILL(2)", "DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};  //操作
    struct node
    {
        int k1,k2;  //k1:第一杯水 k2:第二杯水
        int opnum;   //当前操作
        int nownum,prenum;   //当前下标,前驱
        int step;   //操作步数
        bool operator < (const node &c) const  //步数小的优先出队
        {
            return step > c.step;
        }
    };
    priority_queue<node> q;
    vector<node> v;
    
    void print(int num)   //打印路径
    {
        int idx = 1;
        while(v[num].nownum) //存储下标
        {
            point[idx++] = v[num].nownum;
            num = v[num].prenum;
        }
        int i = idx-1;
        while(i) //输出
        {
            puts(option[v[point[i]].opnum]);
            i--;
        }
    }
    
    void bfs(int x,int y, int ans)
    {
        bool flag = true;
        node now;
        now.k1 = now.k2 = now.nownum = now.prenum = now.step = 0;
        q.push(now);
        vis[0][0] = 1;
        v.push_back(now);
        int idx = 0;
        while(!q.empty())
        {
            now = q.top();
            q.pop();
            if(now.k1 == ans || now.k2 == ans)  //满足条件
            {
                flag =false;
                printf("%d
    ",now.step); //输出步数
                print(now.nownum);  //打印路径
                break;
            }
            node Next;
            for(int i = 1; i <= 6; i++)
            {
                if(i == 1)  //装满第一杯水
                {
                    Next.k1 = x;
                    Next.k2 = now.k2;
                }
                if(i == 2)  //装满第二杯水
                {
                    Next.k1 = now.k1;
                    Next.k2 = y;
                }
                if(i == 3)  //放干第一杯水
                {
                    Next.k1 = 0;
                    Next.k2 = now.k2;
                }
                if(i == 4) //放干第二杯水
                {
                    Next.k1 = now.k1;
                    Next.k2 = 0;
                }
                if(i == 5)  //第一杯水倒入第二杯水中
                {
                    if(now.k1 + now.k2 <= y)  //不能装满或刚好装满第二杯水
                    {
                        Next.k1 = 0;
                        Next.k2 = now.k1+now.k2;
                    }
                    else  //能够装满且还有剩余
                    {
                        Next.k1 = now.k1 + now.k2 - y;
                        Next.k2 = y;
                    }
                }
                if(i == 6) //第二杯水倒入一杯水中
                {
                     if(now.k1+now.k2 <= x) //不能或刚好装满
                     {
                         Next.k1 = now.k1 + now.k2;
                         Next.k2 = 0;
                     }
                     else //装满
                     { 
                         Next.k1 = x;
                         Next.k2 = now.k1 + now.k2 - x;
                     }
                }
                Next.opnum = i;  //记录当前操作下标
                if(!vis[Next.k1][Next.k2])
                {
                    idx++;  //操作次数,当前的操作下标
                    Next.nownum = idx;
                    vis[Next.k1][Next.k2] = 1;
                    Next.step = now.step + 1;
                    Next.prenum = now.nownum;
                    v.push_back(Next);
                    q.push(Next);
                }
            }
        }
        if(flag) puts("impossible");
    }
    int main()
    {
        int A,B,C;
        scanf("%d %d %d",&A,&B,&C);
        bfs(A,B,C);
        return 0;
    }
    

      

  • 相关阅读:
    AFO以后的机房游记
    THUSC2019 退役记
    最小树形图模板
    Codeforces Round #618 (Div. 2)
    「CF662C」 Binary Table
    「SCOI2012」喵星球上的点名
    P4480 「BJWC2018」「网络流与线性规划24题」餐巾计划问题
    CSP-S 2019 游记
    「BZOJ2839」集合计数
    「SPOJ 3105」Power Modulo Inverted
  • 原文地址:https://www.cnblogs.com/Edviv/p/12249617.html
Copyright © 2011-2022 走看看