B - Pour Water 隐式BFS

B - Pour Water

  • 题目:A,B为两水杯量程,C为所求量程。倒水问题 “fill A” 表示倒满A杯,"empty A"表示倒空A杯,“pour A B” 表示把A的水倒到B杯并且把B杯倒满或A倒空。

  • 解题思路:涉及到隐式BFS,自定义结构体node,记录每个结点的两个水杯值以及需要输出的字符串。从(0,0)开始进行BFS,在满足条件的情况下分别执行把A倒满,B倒满,A倒空,B倒空,把A倒给B以及把B倒给A,作为BFS的第一层。例用map将每个结点的上一个结点记录在from中,并将新出现的情况用mp进行标记,未被标记的结点加入队列作为BFS的下一层,每次让s等于队首元素,继续执行六个操作,直到队列为空或是已经得出目标容量C为止,跳出循环。从(0,0)开始递归输出结果,直到from.end,输出结束。

  • 代码实现

#include <iostream>
#include <queue>
#include <string>
#include <map>
using namespace std;

int A,B,C;

struct node
{
	int x,y;
	string choice;
	bool operator<(const node &s) const 
	{
		return x!=s.x ? x<s.x : y<s.y;
	}
};

node s,t;
queue<node> Q;
map<node,node> from;
map<node,bool> mp;

//更新s,t值 
void refresh(node s,node t)
{
	if(from.find(t)==from.end())
	{
		from[t] = s;
		Q.push(t);
	}
}

void print(node &t) 
{
    if (from.find(t) != from.end()) {
        print(from[t]);
        cout<<t.choice<<endl;
    } 
}

void fillA(node s,node t)
{
	t.x=A;
	t.y=s.y;
	if(mp[t]==0){
		mp[t]=1;
		t.choice="fill A";
		refresh(s,t); 
	}		
	else
		return; 
}

void fillB(node s,node t)
{
	t.x=s.x;
	t.y=B;
	if(mp[t]==0){
		mp[t]=1;
		t.choice="fill B";
		refresh(s,t); 
	}
	else 
		return; 
}

void emptyA(node s,node t)
{
	t.x=0;
	t.y=s.y;
	if(mp[t]==0){
		mp[t]=1;
		t.choice="empty A";
		refresh(s,t); 
	}
	else 
		return;  
}

void emptyB(node s,node t)
{
	t.x=s.x;
	t.y=0;
	if(mp[t]==0){
		mp[t]=1;
		t.choice="empty B";
		refresh(s,t); 
	}
	else 
		return; 
}

void AtoB(node s,node t)
{
	t.x=max(s.x+s.y-B,0);
	t.y=min(s.x+s.y,B);
	if(mp[t]==0){
		mp[t]=1;
		t.choice="pour A B";
		refresh(s,t); 
	}
	else 
		return;  
}

void BtoA(node s,node t)
{
	t.x=min(s.x+s.y,A);
	t.y=max(s.x+s.y-A,0);
	t.choice="pour B A";
	if(mp[t]==0){
		mp[t]=1;
		refresh(s,t); 
	}
	else 
		return;  
}

int main()
{
	while(cin>>A>>B>>C)
	{
	mp.clear();
    from.clear();
    while(!Q.empty())
    	Q.pop();
	s.x=0; s.y=0; t.x=0; t.y=0;
	mp[s]=1;
	Q.push(s);
	bool flag=false;
	while(!Q.empty())
	{
		s=Q.front();
		Q.pop();	
		if(s.x==C||s.y==C)
		{
			flag=true;
			print(s);
			break;
	    }
		fillA(s,t);
		fillB(s,t);	
		emptyA(s,t);	
		emptyB(s,t);	
		AtoB(s,t);
		BtoA(s,t);	
	}
	if(flag)
		cout<<"success"<<endl;
	}
	return 0;
}
发布了19 篇原创文章 · 获赞 0 · 访问量 660

猜你喜欢

转载自blog.csdn.net/Hdjjdsbjj/article/details/104609893
今日推荐