【H - Pots】

80 篇文章 0 订阅
80 篇文章 0 订阅

思路:

  • 源自:田益铭的BLOG
  • 这道题做的很崩,勉强做出来居然过掉了。不过以后就会写简单的路径存储了。
  • BFS,6入口,记录路径。
  • 突然发现BFS也不需要优先队列啊…普通队列就行了呀。
  • 第一次做记录路径的搜索,总结如下:
    1. 结构体要保存:状态(x,y),深度(step),前驱(pre)。
    2. 需要一个数组存储 pot,什么时候用呢,就是当丢掉一个 pot 时紧接着存起来就可以了。
    3. 发现带有构造函数的结构体不能使用数组。
    4. 需要一个来实现反向输出。

代码:

  • 0ms 696kB
//0ms	696kB


#include <iostream>
#include <queue>
#include <cstring>
#include <stack>

using namespace std;

const int maxn = 105;

bool vis[maxn][maxn];
bool ok = false;
int A,B,C;
struct pot{
	int x,y;//the water in pot A,B
	int step;
	int ope;//operator from 1 ... 6 , 0代表开始状态 
	int pre;
	//pot(int x,int y,int step,pot *pre) : x(x) , y(y) , step(step) , pre(pre) {} ;
};//带有这种构造函数的结构体不能使用数组
pot path[maxn * maxn];int cnt = 1;//from 1 ... cnt-1
queue<pot> Q;
int theend;
int ans;
stack<int> S;

void Mypush(int x,int y,int step,int ope,int pre){
	pot temp;
	temp.x = x;
	temp.y = y;
	temp.step = step;
	temp.ope = ope;
	temp.pre = pre;
	Q.push(temp);
	return ;
}

void Stretch(pot cur){
	for(int i=1;i<=6;i++){
		int x , y;
		int step ;
		switch (i)
		{
			case 1 :
				x = A , y = cur.y;break;
			case 2 :
				x = cur.x , y = B;break;
			case 3 :
				x = 0 , y = cur.y;break;
			case 4 :
				x = cur.x , y = 0;break;
			case 5 :
				if(cur.x + cur.y <= B)
					x = 0 , y = cur.x + cur.y;
				else
					x = cur.x + cur.y - B , y = B;
				break;
			case 6 :
				if(cur.x + cur.y <= A)
					x = cur.x + cur.y , y = 0;
				else
					x = A , y = cur.x + cur.y - A;
				break; 
		}
		step = cur.step + 1;
		if(vis[x][y])
			continue;
		vis[x][y] = true;
		Mypush(x , y , step , i , cnt-1);
	}
	return ;
}

void BFS(){
	Mypush(0,0,0,0,0);
	vis[0][0] = true;
	while(!Q.empty()){
		pot cur = Q.front();Q.pop();
		path[cnt++] = cur;//from 1 ... cnt-1
		if(cur.x == C || cur.y == C){
			ok = true;
			theend = cnt-1;
			ans = cur.step;
			return ;
		}
		Stretch(cur);
	}
	return ;//ok is still false
}

void Output(){
	if(!ok){
		cout<<"impossible"<<endl;
		return ;
	}
	cout<<ans<<endl;
	pot cur=path[theend];
	while(cur.pre){
		S.push(cur.ope);
		cur = path[cur.pre];
	}
	while(S.size()){
		int i = S.top() ; S.pop();
		switch (i){
			case 1 : cout<<"FILL(1)"<<endl;break;
			case 2 : cout<<"FILL(2)"<<endl;break;
			case 3 : cout<<"DROP(1)"<<endl;break;
			case 4 : cout<<"DROP(2)"<<endl;break;
			case 5 : cout<<"POUR(1,2)"<<endl;break;
			case 6 : cout<<"POUR(2,1)"<<endl;break;
		}
	}
	return ;
}

int main(){
	cin>>A>>B>>C;
	memset(vis,false,sizeof(vis));
	BFS();
	Output();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值