caioj1048: 宽搜3(巧妙取量)

博客讨论了一个利用宽度优先搜索(BFS)解决三容器倒油问题的算法,其中容器容量分别为a, b, c。问题要求确定是否能仅通过这三个容器倒出k升油,并给出最少倒油次数。博主分享了自己在解决这个问题时遇到的边界条件和代码实现上的错误,并给出了样例输入和输出。" 113724353,10547897,前后端连接MySQL数据库实战,"['前端开发', '后端开发', '数据库', 'Java', 'JDBC']
摘要由CSDN通过智能技术生成

【闲话】

折磨了我一天的一题qaq刚刚去问了杜老师qaq帮我仔细一点点看了代码 最后被自己蠢哭....没有考虑倒0次的时候..以及!!!!不能把主函数的ans直接用bfs(s)替换掉 因为else里面的是重新算的 如果非要这样的话在else里面要重新初始化f数组

考虑边界啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

【题目描述】 
有三个容器,容量分别为 a,b,c(a> b > c ),一开始a装满油,现在问是否只靠abc三个容器量出k升油。
如果能就输出“yes”,并且说明最少倒几次,否则输出“no”。
例如:10升油在10升的容器中,另有两个7升和3升的空容器,要求用这三个容器倒油,
使得最后在abc三个容器中有一个刚好存有5升油,问最少的倒油次数是多少?
(每次倒油,A容器倒到B容器,或者A内的油倒完,或者B容器倒满。 )
  10 7 3 
(10 0 0) 
 (3 7 0):第一次 
 (3 4 3):第二次 
 (6 4 0):第三次 
 (6 1 3):第四次 
 (9 1 0):第五次 
 (9 0 1):第六次 
 (2 7 1):第七次 
 (2 5 3):第八次,出现5了。

【输入格式】
输入有多组测试数据。
输入a,b,c, k四个正整数( 100 a > b > c > = 1 , 1 < = k < 100 )
【输出格式】
如果能得到k就输出两行
第一行“yes”,第二行为最少的次数,否则输出“no”
【样例输入】
10 7 3 5
【样例输出】
yes
8
【代码1】自己写的qaq

#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
struct state{
	int a,b,c,step;
}s,e;
int a,b,c,k;
bool f[105][105][105];

int bfs(state x){
	queue<state> q;
	q.push(x);
	f[x.a][x.b][x.c]=true;
	while(!q.empty()){
		state cur=q.front();
		q.pop();
		if(cur.a==k||cur.b==k||cur.c==k){
			return cur.step;
		}
		if(cur.a>0&&cur.b<b){     //v1->v2
		  int t=min(cur.a,b-cur.b);
		  state temp;
		  temp.a=cur.a-t;
		  temp.b=cur.b+t;
		  temp.c=cur.c;
		  temp.step=cur.step+1;
		  if(!f[temp.a][temp.b][temp.c]){
		  	q.push(temp);
		  	f[temp.a][temp.b][temp.c]=1;
		  }
		}
		if(cur.a>0&&cur.c<c){     //v1->v3
		  int t=min(cur.a,c-cur.c);
		  state temp;
		  temp.a=cur.a-t;
		  temp.b=cur.b;
		  temp.c=cur.c+t;
		  temp.step=cur.step+1;
		  if(!f[temp.a][temp.b][temp.c]){
		  	q.push(temp);
		  	f[temp.a][temp.b][temp.c]=1;
		  }
		}
		if(cur.b>0&&cur.c<c){     //v2->v3
		  int t=min(cur.b,c-cur.c);
		  state temp;
		  temp.a=cur.a;
		  temp.b=cur.b-t;
		  temp.c=cur.c+t;
		  temp.step=cur.step+1;
		  if(!f[temp.a][temp.b][temp.c]){
		  	q.push(temp);
		  	f[temp.a][temp.b][temp.c]=1;
		  }
		}
		if(cur.b>0&&cur.a<a){     //v2->v1
		  int t=min(cur.b,a-cur.a);
		  state temp;
		  temp.a=cur.a+t;
		  temp.b=cur.b-t;
		  temp.c=cur.c;
		  temp.step=cur.step+1;
		  if(!f[temp.a][temp.b][temp.c]){
		  	q.push(temp);
		  	f[temp.a][temp.b][temp.c]=1;
		  }
		}
		if(cur.c>0&&cur.a<a){     //v3->v1
		  int t=min(cur.c,a-cur.a);
		  state temp;
		  temp.a=cur.a+t;
		  temp.b=cur.b;
		  temp.c=cur.c-t;
		  temp.step=cur.step+1;
		  if(!f[temp.a][temp.b][temp.c]){
		  	q.push(temp);
		  	f[temp.a][temp.b][temp.c]=1;
		  }
		}
		if(cur.c>0&&cur.b<b){     //v3->v2
		  int t=min(cur.c,b-cur.b);
		  state temp;
		  temp.a=cur.a;
		  temp.b=cur.b+t;
		  temp.c=cur.c-t;
		  temp.step=cur.step+1;
		  if(!f[temp.a][temp.b][temp.c]){
		  	q.push(temp);
		  	f[temp.a][temp.b][temp.c]=1;
		  }
		}
	}
	return -1;//可以倒0次!!! 
} 
int main(){
	while(~scanf("%d%d%d%d",&a,&b,&c,&k)){
		s.a=a,s.b=0,s.c=0,s.step=0;
		memset(f,0,sizeof(f));
		int ans=bfs(s);
		if(ans==-1) printf("no\n");
        else{
        	printf("yes\n%d\n",ans);
		}
	}
	return 0;
}
【代码2】老师的qwq
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct State{
	int a,b,c;
	int step;
};
State b,e;
int v1,v2,v3,k;
bool f[105][105][105];

bool bfs(State b){
	queue<State> q;
	q.push(b);
	f[b.a][b.b][b.c] = true;
	State cur;
	while (!q.empty()){
		cur = q.front() ;
		if (cur.a==k || cur.b==k || cur.c==k){
			printf("yes\n%d\n",cur.step);
			return true;
		}
		q.pop();
		
		if (cur.a>0 && cur.b<v2){       // v1 -> v2
			int t=min(cur.a,v2-cur.b);
			State temp;
			temp.a = cur.a-t;
			temp.b = cur.b+t;
			temp.c = cur.c;
			temp.step = cur.step+1;
			if (!f[temp.a][temp.b][temp.c]){
				q.push(temp);
				f[temp.a][temp.b][temp.c] = true;
			}
		}
		
		if (cur.a>0 && cur.c<v3){       // v1 -> v3
			int t=min(cur.a,v3-cur.c);
			State temp;
			temp.a = cur.a-t;
			temp.b = cur.b;
			temp.c = cur.c+t;
			temp.step = cur.step+1;
			if (!f[temp.a][temp.b][temp.c]){
				q.push(temp);
				f[temp.a][temp.b][temp.c] = true;
			}
		}
		
		if (cur.b>0 && cur.a<v1){       // v2 -> v1
			int t=min(cur.b,v1-cur.a);
			State temp;
			temp.a = cur.a+t;
			temp.b = cur.b-t;
			temp.c = cur.c;
			temp.step = cur.step+1;
			if (!f[temp.a][temp.b][temp.c]){
				q.push(temp);
				f[temp.a][temp.b][temp.c] = true;
			}
		}
		
		if (cur.b>0 && cur.c<v3){       // v2 -> v3
			int t=min(cur.b,v3-cur.c);
			State temp;
			temp.a = cur.a;
			temp.b = cur.b-t;
			temp.c = cur.c+t;
			temp.step = cur.step+1;
			if (!f[temp.a][temp.b][temp.c]){
				q.push(temp);
				f[temp.a][temp.b][temp.c] = true;
			}
		}
		
		if (cur.c>0 && cur.a<v1){       // v3 -> v1
			int t=min(cur.c,v1-cur.a);
			State temp;
			temp.a = cur.a+t;
			temp.b = cur.b;
			temp.c = cur.c-t;
			temp.step = cur.step+1;
			if (!f[temp.a][temp.b][temp.c]){
				q.push(temp);
				f[temp.a][temp.b][temp.c] = true;
			}
		}
		
		if (cur.c>0 && cur.b<v2){       // v3 -> v2
			int t=min(cur.c,v2-cur.b);
			State temp;
			temp.a = cur.a;
			temp.b = cur.b+t;
			temp.c = cur.c-t;
			temp.step = cur.step+1;
			if (!f[temp.a][temp.b][temp.c]){
				q.push(temp);
				f[temp.a][temp.b][temp.c] = true;
			}
		}
	}
	return false;
}

int main(){
	while (~scanf("%d%d%d%d",&v1,&v2,&v3,&k)){
		b.a=v1; b.b=0; b.c=0; b.step=0;	
		memset(f,0,sizeof(f));
		if (!bfs(b)) printf("no\n");
	}		
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值