题目链接:点我
【题目描述】
有三个容器,容量分别为 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
我使用的是map<int,bool>,就是将a,b,c转换为int数值,网上有使用bool isExist[100][100][100]三维数组的,其实差不多,随你开心!
#include <stdio.h>
#include <queue>
#include <map>
using namespace std;
int a, b, c, k;
map<int, bool> intMapBool;
struct Node {
int a, b, c;
int stepNum, lastStep;//步骤数和上一步骤
} startNode, tempNode;
int toIntByNums(int Ca, int Cb, int Cc) {
//由于100>=a>b>c>=1,可以将a,b,c拼接为一个hash整数
return Ca * 10000 + Cb * 100 + Cc;
}
void handle(int &Ca, int &Cb, int which) {
if(Ca != 0) {
int need = which - Cb;
if(Ca >= need) {
Cb = which;
Ca -= need;
} else {
Cb += Ca;
Ca = 0;
}
}
}
//有了map后,这个办法有点重复了,我还是保留着
bool check(int lastStep, int step) {
//a倒给b,b就别倒给a
if(lastStep == 0 && step == 2) return false;
//a倒给c,c就别倒给a
if(lastStep == 1 && step == 4) return false;
if(lastStep == 2 && step == 0) return false;
if(lastStep == 3 && step == 5) return false;
if(lastStep == 4 && step == 1) return false;
if(lastStep == 5 && step == 3) return false;
return true;
}
void bfs() {
//清除数据
intMapBool.clear();
queue<Node> q;
bool flag = true;
startNode.a = a;
startNode.lastStep = -1;
intMapBool[toIntByNums(a, 0, 0)] = true;
q.push(startNode);
while(!q.empty()) {
Node top = q.front();
q.pop();
if(top.a == k || top.b == k || top.c == k) {
printf("yes\n%d\n", top.stepNum);
flag = false;
return;
}
for(int i = 0; i < 6; i++) {
//防止内存超限或者运行超时!
if(check(top.lastStep, i) == false) continue;
tempNode.a = top.a;
tempNode.b = top.b;
tempNode.c = top.c;
switch(i) {
case 0:
//a倒给b
handle(tempNode.a, tempNode.b, b);
tempNode.lastStep = i;
break;
case 1:
//a倒给c
handle(tempNode.a, tempNode.c, c);
tempNode.lastStep = i;
break;
case 2:
//b倒给a
handle(tempNode.b, tempNode.a, a);
tempNode.lastStep = i;
break;
case 3:
//b倒给c
handle(tempNode.b, tempNode.c, c);
tempNode.lastStep = i;
break;
case 4:
//c倒给a
handle(tempNode.c, tempNode.a, a);
tempNode.lastStep = i;
break;
case 5:
//c倒给b
handle(tempNode.c, tempNode.b, b);
tempNode.lastStep = i;
break;
}
int value = toIntByNums(tempNode.a, tempNode.b, tempNode.c);
if(intMapBool[value] == false) {
tempNode.stepNum = top.stepNum + 1;
q.push(tempNode);
intMapBool[value] = true;
}
}
}
if(flag) printf("no\n");
}
int main() {
while(~scanf("%d %d %d %d", &a, &b, &c, &k)) {
if(k <= a) {
bfs();
} else {
printf("no\n");
}
}
return 0;
}