题意:有两个固定大小的容器,通过对容器内水的操作,使得至少一个容器内的液体量达到规定的量,求出操作数最少的操作步骤
我写的比较繁琐,将各种操作封装在了结构体里,然后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();
}