问题 E: 【宽搜入门】巧妙取量
题目描述
有三个容器,容量分别为 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了。
Input
【输入格式】
有多组测试数据。
输入a,b,c, k四个正整数( 100 ≥ a > b > c≥1 , 1≤k< 100 )
Output
【输出格式】
如果能得到k就输出两行。
第一行“yes”,第二行为最少的次数
否则输出“no”
Sample Input
10 7 3 5
Sample Output
yes 8
AC代码:
#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;
}
参考:https://blog.csdn.net/qq_39402039/article/details/78162027