*Step.4 算法 ACM广度优先搜索(BFS) 非常可乐【倒水问题+BFS】

本文介绍了一道经典的算法题目,通过六种不同的倒水方式寻找特定状态的解决方案。利用广度优先搜索(BFS)策略,确保不重复探索相同状态,并详细展示了每一步倒水操作的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.hdu.edu.cn/showproblem.php?pid=1495

个人意见,值得一看。

思路,总共6种倒水方式,把每种都倒一遍就行了,符合bfs。注意对已经倒过的情况保存记录,防止重复倒入。

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int mm,nn,ss;
bool vis[105][105];
struct Node{
	int m,n,s,t=0;
}; 
void msort(){
	if(mm>nn){
		int t=mm;
		mm=nn;
		nn=t;
	}
	if(nn>ss){
		int t=nn;
		nn=ss;
		ss=t;
	}

}
int main(){
	while(cin>>ss>>nn>>mm&&ss!=0){
		memset(vis,0,sizeof(vis));
		msort();		
		if(ss%2==1){
			cout<<"NO"<<endl;
			continue;
		}
		Node n;
		n.m=0;
		n.n=0;
		n.s=ss;
		vis[0][0]=true;
		queue<Node>q;
		q.push(n);
		bool flag=false;
		while(!q.empty()){
			Node node=q.front();
			q.pop();
			if(node.m==0&&node.n==node.s){
				flag=true;
				cout<<node.t<<"\n";
				break;
			}
		
			//接下来就是倒水了
			//6种倒水的方法
			//m->n m->s  n->m n->s  s->m s->n
			//倒水的原则: 看目标是不是满了,不满就倒
			//倒水的结果,将倒水的容器的水全倒进去,
			//如果目标的水大于容量, 倒水的容器为 差值
			//否则,为零 
			
			//1	m->n
			if(node.n<nn){
				Node n1=node;
				n1.n+=n1.m;
				if(n1.n<=nn){
					n1.m=0;
				}else{
					n1.m=n1.n-nn;
					n1.n=nn;
				}
				n1.t++;
				if(!vis[n1.m][n1.n]){
					vis[n1.m][n1.n]=true;q.push(n1);
				}
				
			} 
			
			//2	m->s
			if(node.s<ss){
				Node n1=node;
				n1.s+=n1.m;
				if(n1.s<=ss){
					n1.m=0;
				}else{
					n1.m=n1.s-ss;
					n1.s=ss;
				}
				n1.t++;
				if(!vis[n1.m][n1.n]){
					vis[n1.m][n1.n]=true;q.push(n1);
				}
			} 
			
			//3 n->m
			if(node.m<mm){
				Node n1=node;
				n1.m+=n1.n;
				if(n1.m<=mm){
					n1.n=0;
				}else{
					n1.n=n1.m-mm;
					n1.m=mm;
				}
				n1.t++;
				if(!vis[n1.m][n1.n]){
					vis[n1.m][n1.n]=true;q.push(n1);
				}
			} 	
			
			//4 n->s
			if(node.s<ss){
				Node n1=node;
				n1.s+=n1.n;
				if(n1.s<=ss){
					n1.n=0;
				}else{
					n1.n=n1.s-ss;
					n1.s=ss;
				}
				n1.t++;
				if(!vis[n1.m][n1.n]){
					vis[n1.m][n1.n]=true;q.push(n1);
				}
			} 	
			
			//5 s->m			
			if(node.m<mm){
				Node n1=node;
				n1.m+=n1.s;
				if(n1.m<=mm){
					n1.s=0;
				}else{
					n1.s=n1.m-mm;
					n1.m=mm;
				}
				n1.t++;
				if(!vis[n1.m][n1.n]){
					vis[n1.m][n1.n]=true;q.push(n1);
				}
			} 
			
			//6 s->n			
			if(node.n<nn){
				Node n1=node;
				n1.n+=n1.s;
				if(n1.n<=nn){
					n1.s=0;
				}else{
					n1.s=n1.n-nn;
					n1.n=nn;
				}
				n1.t++;
				if(!vis[n1.m][n1.n]){
					vis[n1.m][n1.n]=true;q.push(n1);
				}
			} 
		}
		if(!flag)cout<<"NO"<<endl;//有可能有 即使把所有情况遍历一遍也没有找到的元素。 
		
		
	}
	
	return 0;
} 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值