POJ3414 Pots(BFS+记录路径)

题目传送门
话说BFS的搜索树我觉得还是挺巧妙的,这道题用到了用struct入队,还是相对来说比较巧妙。
首先这道题每一个操作步骤都有6个分支:
1.装满1
2.装满2
3.倒空1
4.倒空2
5.1倒2
6.2倒1
六个搜索分支因为只有六种情况,所以可以用一个string数组来存储这六种状态,只用记录这个状态所对应的数组下标的顺序,当然题目读到这,我还是没有立刻想到用bfs来完成本题,接下来,题目要求搜索到步骤最小的情况,因此必是bfs。
既然是BFS搜索树,那必然是每种情况都先入队,在每一种情况的最先开始的时候用一个新定义的结构体,来存这些状态,因为这六种不同的状态在本过程是互斥的,因此不能全权存储。
当然本题在每一种不同的情况的易错点就在于:先运算,再赋值要不然就会感受到Wonderful Accept的快感。

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
string s[10]={"   ","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
bool st[210][210];
struct node{
	int a,b;
	int num;
	int t[210];
}bo;
queue<node>q;
int main(){
//	cout<<s[1]<<endl;
	int aa,bb,c;
	cin>>aa>>bb>>c;
	bo.a=0;
	bo.b=0;
	bo.num=0;
	q.push(bo);
	st[0][0]=true;
	while(q.size()){
		//cout<<"ok"<<endl;
		node now=q.front();
		q.pop();
	//	cout<<now.a<<' '<<now.b<<endl;
		if(now.a==c||now.b==c){
			
			printf("%d\n",now.num);
			for(int i=1;i<=now.num;i++){
				//cout<<now.t[i]<<endl;
				cout<<s[now.t[i]]<<endl;
				
			}return 0;
		}
		for(int i=1;i<=6;i++){
		node af=now;af.num++;
		           //                    cout<<af.num<<endl;
			if(i==1&&af.a!=aa){
				af.a=aa;
				if(!st[af.a][af.b]){
					st[af.a][af.b]=true;
					af.t[af.num]=1;
					q.push(af);
				}
			}else if(i==2&&af.b!=bb){
				af.b=bb;
				if(!st[af.a][af.b]){
					st[af.a][af.b]=true;
					af.t[af.num]=2;
					q.push(af);
				}
			}else if(i==3&&af.a!=0){
				af.a=0;
				if(!st[af.a][af.b]){
					st[af.a][af.b]=true;
					af.t[af.num]=3;
					q.push(af);
				}
			}else if(i==4&&af.b!=0){
				af.b=0;
				if(!st[af.a][af.b]){
					st[af.a][af.b]=true;
					af.t[af.num]=4;
					q.push(af);
				}
			}else if(i==5){
			//	cout<<"555or:"<<"  "<<af.a<<" "<<af.b<<endl;
				if(bb-af.b>=af.a){
					
					af.b+=af.a;af.a=0;
				}else {
					af.a+=af.b-bb;
					af.b=bb;
				}
			//	cout<<"555end:"<<"  "<<af.a<<" "<<af.b<<endl;
				if(!st[af.a][af.b]){
					st[af.a][af.b]=true;
					af.t[af.num]=5;
					q.push(af);
				}
			}else if(i==6){
			//	cout<<"666or:"<<"  "<<af.a<<" "<<af.b<<endl;
				if(aa-af.a>=af.b){
					
					af.a+=af.b;af.b=0;
				}else {
					af.b+=af.a-aa;
					af.a=aa;
				}
			//	cout<<"666end:"<<"  "<<af.a<<" "<<af.b<<endl;
				if(!st[af.a][af.b]){
					st[af.a][af.b]=true;
					af.t[af.num]=6;
					q.push(af);
				}
			}
		}
	}
	printf("impossible\n");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值