题目来源:http://codeup.cn/problem.php?cid=100000609&pid=4
题目描述
【题目描述】
有三个容器,容量分别为 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
#include <iostream>
#include <cstring>
#include <fstream>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
struct level{
int num[3],step;
};
int BFS(level have,level full, int k){
int record[101][100][100]={0};
queue<level> list;
list.push(have);
record[have.num[0]][have.num[1]][have.num[2]] =1;
while(!list.empty()){
level now=list.front();
list.pop();
if(now.num[0]==k || now.num[1]==k || now.num[2]==k)
return now.step;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
level next;
if(i==j ||
now.num[i]==0 ||
now.num[j]==full.num[j]) {
continue;
}
int t=now.num[i]-(full.num[j]-now.num[j]);
if(t<0){
next.num[i]=0;
next.num[j]=now.num[j]+now.num[i];
}
else{
next.num[i]=t;
next.num[j]=full.num[j];
}
next.step=now.step+1;
next.num[3-i-j]=now.num[3-i-j];
if(!record[next.num[0]][next.num[1]][next.num[2]]){
list.push(next);
record[next.num[0]][next.num[1]][next.num[2]]=1;
}
}
}
}
return -1;
}
int main()
{
level have,full;
int k;
while(~scanf("%d %d %d %d",&full.num[0],&full.num[1],&full.num[2],&k)) {
have={0};
have.num[0] = full.num[0];
int t = BFS(have,full,k);
if (t < 0) {
printf("no\n");
} else {
printf("yes\n%d\n", t);
}
}
return 0;
}