题目描述
【题目描述】
有三个容器,容量分别为 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<vector>
#include<cstdio>
using namespace std;
struct oil_box //油桶
{
int oil_left; //桶内剩余油量
int volume_left; //桶内剩余空间
};
int target_oil;//目标油量
int step_min = 50;//当前最小步数,初始设为50步
int oil_total; //总油量
void DFS(vector<oil_box> vc, int index_a, int index_b, int step)//向量vc存储所有油桶的信息,index_a是上一次出油的油桶索引,index_b是上一次接油的油桶索引,step为当前步数
{
if (step >=step_min || (vc[0].oil_left==oil_total&&step!=1))//剪枝
{
return;
}
int len = vc.size();
for (int i = 0; i < len; i++)
{
int index_now = i;
oil_box box_now = vc[index_now];
if (box_now.oil_left != 0)
{
for (int j = 1; j < len; j++)
{
int index_next = (index_now + j) % len;
oil_box box_next = vc[index_next];
if (index_now != index_b || index_next != index_a)//避免进入死循环
{
if (box_now.oil_left > box_next.volume_left)
{
box_now.oil_left = box_now.oil_left - box_next.volume_left;
box_now.volume_left = box_now.volume_left + box_next.volume_left;
box_next.oil_left = box_next.oil_left + box_next.volume_left;
box_next.volume_left = 0;
}
else
{
box_next.oil_left = box_next.oil_left + box_now.oil_left;
box_next.volume_left = box_next.volume_left - box_now.oil_left;
box_now.volume_left = box_now.volume_left + box_now.oil_left;
box_now.oil_left = 0;
}
if (box_now.oil_left == target_oil || box_next.oil_left == target_oil)
{
if (step < step_min)
{
step_min = step;
}
return;
}
vector<oil_box> vc_new = vc;
vc_new[index_now] = box_now;
vc_new[index_next] = box_next;
DFS(vc_new, index_now,index_next, step + 1);
}
}
}
}
}
int main()
{
oil_box a, b, c;
scanf("%d%d%d%d", &a.oil_left, &b.volume_left, &c.volume_left, &target_oil);
oil_total = a.oil_left;
a.volume_left = 0;
b.oil_left = 0;
c.oil_left = 0;
vector<oil_box> vc;
vc.push_back(a);
vc.push_back(b);
vc.push_back(c);
DFS(vc, 0, 0, 1);
if (step_min != 50)
{
printf("%s\n", "yes");
printf("%d", step_min);
}
else
{
printf("%s", "no");
}
return 0;
}