OpenJ_Bailian 3151 Pots (BFS)

题意:有两个固定大小的容器,通过对容器内水的操作,使得至少一个容器内的液体量达到规定的量,求出操作数最少的操作步骤

我写的比较繁琐,将各种操作封装在了结构体里,然后BFS

代码:

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 10000000007
#define mem(a) memset(a,0,sizeof(a))

using namespace std;

typedef pair <int,int> pii;
const int maxn = 10000+5 , inf = 0x3f3f3f3f;
int C;
int a[3];
bool vis[maxn][maxn];
struct Node{
    int i,j,id,f,flag;
    int A,B;
    Node(int ii=0,int jj=0,int ff=0,int idd=0,int flagg=0,int AA=0,int BB=0):i(ii),j(jj),f(ff),id(idd),flag(flagg),A(AA),B(BB){};
    void FILL(){
        if(i==1) A=a[1];
        else B=a[2];
    }
    void DROP(){
        if(i==1) A=0;
        else B=0;
    }
    void POUR(){
        if(i==1&&j==2){
            if(A>a[2]-B){
                A-=(a[2]-B);
                B=a[2];
            }
            else{
                B+=A;
                A=0;
            }
        }
        if(i==2&&j==1){
            if(B>a[1]-A){
                B-=(a[1]-A);
                A=a[1];
            }
            else{
                A+=B;
                B=0;
            }
        }
    }
    void print(){
        if(j==0){
            if(flag==1){
                if(i==1) cout<<"FILL(1)"<<endl;
                if(i==2) cout<<"FILL(2)"<<endl;
            }
            if(flag==3){
                if(i==1) cout<<"DROP(1)"<<endl;
                if(i==2) cout<<"DROP(2)"<<endl;
            }
        }else{
            if(i==1&&j==2) cout<<"POUR(1,2)"<<endl;
            if(i==2&&j==1) cout<<"POUR(2,1)"<<endl;
        }
    }
}oper[maxn];

bool judge(Node now){
    if(now.A==C||now.B==C) return true;
    return false;
}
vector<Node>path;
int find_path(Node u){
    while(u.f!=u.id){
        path.push_back(u);
        u = oper[u.f];
    }
    path.push_back(u);
    cout<<path.size()<<endl;
    for(int i=path.size()-1;i>=0;i--)
        path[i].print();
}

void bfs(){
    vis[0][0] = true;
    Node tmp1(1,0,0,0,1,0,0);oper[0]=tmp1;
    Node tmp2(2,0,1,1,1,0,0);oper[1]=tmp2;
    Node tmp3(1,2,2,2,2,0,0);oper[2]=tmp3;
    Node tmp4(2,1,3,3,2,0,0);oper[3]=tmp4;
    Node tmp5(1,0,4,4,3,0,0);oper[4]=tmp5;
    Node tmp6(2,0,5,5,3,0,0);oper[5]=tmp6;
    queue<Node>q;
    q.push(tmp1);
    q.push(tmp2);
    q.push(tmp3);
    q.push(tmp4);
    q.push(tmp5);
    q.push(tmp6);
    int cnt = 6;
    while(!q.empty()){
        Node now = q.front();q.pop();
        if(now.j==0){
            if(now.flag==1) now.FILL();
            if(now.flag==3) now.DROP();
        }
        else now.POUR();
        if(judge(now)){
            find_path(now);
            return ;
        }
        if(!vis[now.A][now.B]){
            vis[now.A][now.B] = true;
            Node tmp1(1,0,now.id,cnt,1,now.A,now.B);oper[cnt++]=tmp1;q.push(tmp1);
            Node tmp2(2,0,now.id,cnt,1,now.A,now.B);oper[cnt++]=tmp2;q.push(tmp2);
            Node tmp3(1,2,now.id,cnt,2,now.A,now.B);oper[cnt++]=tmp3;q.push(tmp3);
            Node tmp4(2,1,now.id,cnt,2,now.A,now.B);oper[cnt++]=tmp4;q.push(tmp4);
            Node tmp5(1,0,now.id,cnt,3,now.A,now.B);oper[cnt++]=tmp5;q.push(tmp5);
            Node tmp6(2,0,now.id,cnt,3,now.A,now.B);oper[cnt++]=tmp6;q.push(tmp6);
        }
    }
    cout<<"impossible"<<endl;
}

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d%d%d",&a[1],&a[2],&C);
      bfs();
}

猜你喜欢

转载自blog.csdn.net/Insist_77/article/details/81480058