OpenJudge3151 Pots(BFS隐式图)

题目链接

  • 题意:

有两个体积分别为A、B的容器,容器的起始状态为空,要求通过执行fill a/b、empty a(b) b(a)、pour a(b) b(a)六种操作使其中一个容器中装有体积为C的水,记录并输出操作过程

  • 思路:

BFS隐式图问题,以两个容器中盛有水的体积作为本题的状态则初始结点为(0,0),目标结点为(C,0)或(0,C),中间结点为经过不同操作后容器中的盛水状态,从初始结点开始执行一次BFS直到队头元素为目标结点,从此时的队头元素开始向前回溯记录路径,最后输出操作过程。

  • 代码实现:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;

int a,b,c;
bool vis[110][110];

struct s{
	int pot1;
	int pot2;
	int steps;
	int op;
	int father;
	s(){}
	s(int p1,int p2,int s,int o,int f):pot1(p1),pot2(p2),steps(s),op(o),father(f){}
};



void Output(int op){
	switch(op){
		case 0:
			cout<<"FILL(1)"<<endl;
			break;
		case 1:
			cout<<"FILL(2)"<<endl;
			break;
		case 2:
			cout<<"DROP(1)"<<endl;
			break;			
		case 3:
			cout<<"DROP(2)"<<endl;
			break;
		case 4:
			cout<<"POUR(1,2)"<<endl;
			break;
		case 5:
			cout<<"POUR(2,1)"<<endl;
			break;										
	}
}


int main()
{
	ios::sync_with_stdio(false);
	while(cin>>a>>b>>c){
		memset(vis,0,sizeof(vis));
		s q[50000];
		int head,tail;
		head=tail=0;
		vis[0][0]=1;
		q[tail++]=s(0,0,0,-1,-1);
		bool flag=false;
		while(head!=tail){
			s t=q[head];
			if(t.pot1==c||t.pot2==c){
				flag=true;
				break;
			}
			if(!vis[a][t.pot2]){
				vis[a][t.pot2]=1;
				q[tail++]=s(a,t.pot2,t.steps+1,0,head);
			}
			if(!vis[t.pot1][b]){
				vis[t.pot1][b]=1;
				q[tail++]=s(t.pot1,b,t.steps+1,1,head);
			}
			if(!vis[0][t.pot2]){
				vis[0][t.pot2]=1;
				q[tail++]=s(0,t.pot2,t.steps+1,2,head);
				
			}
			if(!vis[t.pot1][0]){
				vis[t.pot1][0]=1;
				q[tail++]=s(t.pot1,0,t.steps+1,3,head);				
			}
			int sum=t.pot1+t.pot2;
			if(sum>b){
				if(!vis[sum-b][b]){
					vis[sum-b][b]=1;
					q[tail++]=s(sum-b,b,t.steps+1,4,head);
				}
			}
			if(sum<=b){
				if(!vis[0][sum]){
					vis[0][sum]=1;
					q[tail++]=s(0,sum,t.steps+1,4,head);
				}
			}
			if(sum>a){
				if(!vis[a][sum-a]){
					vis[a][sum-a]=1;
					q[tail++]=s(a,sum-a,t.steps+1,5,head);
				}
			}
			if(sum<=a){
				if(!vis[sum][0]){
					vis[sum][0]=1;
					q[tail++]=s(sum,0,t.steps+1,5,head);
				}
			}			
			head++;
		}
		if(!flag){
			cout<<"impossible"<<endl;
			continue;
		}
		vector<s> res;
		s path=q[head];
		while(path.father!=-1){
			res.push_back(path);
			path=q[path.father];
		}
		cout<<res.size()<<endl;
		for(int i=res.size()-1;i>=0;i--){
			Output(res[i].op);
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值