题意:给你两个壶,容量分别为a,b,初始都是0,再给你一个目标水量c,问经过几次操作可以使得其中一个壶的水量为目标水量c,并且把操作步骤输出。
6个操作:
1、FILL(1)//FILL(i),把 i 壶装满
2、FILL(2)
3、DROP(1)//DROP(i),把 i 壶倒光
4、DROP(2)
5、POUR(1,2)//POUR(i,j)从 i 壶里倒水到 j 壶,直至 i 壶空了,或者 j 壶满了
6、POUR(2,1)
bfs最短路,关键点:
队列元素:两个壶的水量、在队列里的位置、上一个操作在队列里的位置、达到这个水量的操作(这三步是为了记录路径)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int ms = 3e6;
struct node{
int a,b;
int index;
int way;
int last;
};
node queue[ms];
int front,rear,visit[105][105] = {0},path[ms];
void Init(){
front = rear = 0;
}
bool IsEmpty(){
if(front == rear)
return true;
return false;
}
void Push(node x){
if(visit[x.a][x.b])
return;
visit[x.a][x.b] = 1;
x.index = rear;
queue[rear++] = x;
return;
}
void Pop(){
front++;
return;
}
void Print(int w){
if(w == 1){
printf("FILL(1)\n");
return;
}
if(w == 2){
printf("FILL(2)\n");
return;
}
if(w == 3){
printf("DROP(1)\n");
return;
}
if(w == 4){
printf("DROP(2)\n");
return;
}
if(w == 5){
printf("POUR(1,2)\n");
return;
}
if(w == 6){
printf("POUR(2,1)\n");
return;
}
return;
}
int main(){
int m1,m2,c,k;
while(scanf("%d %d %d",&m1,&m2,&c) != EOF){
k = -1;
Init();
node start;
start.a = start.b = 0;
start.index = 0;
start.last = -1;
start.way = -1;
queue[0] = start;
rear = 1;
visit[0][0] = 1;
while(!IsEmpty()){
node top = queue[front];
Pop();
if(top.a ==c || top.b ==c){
int pos = top.index;
while(queue[pos].way != -1){
path[++k] = queue[pos].way;
pos = queue[pos].last;
}
printf("%d\n",k+1);
while(k >= 0){
Print(path[k]);
k--;
}
k = 0;
break;
}
node newn;
newn.last = top.index;
//FILL(1) = 1;
newn.a = m1;
newn.b = top.b;
newn.way = 1;
Push(newn);
//FILL(2) = 2;
newn.a = top.a;
newn.b = m2;
newn.way = 2;
Push(newn);
//DROP(1) = 3;
newn.a = 0;
newn.b = top.b;
newn.way = 3;
Push(newn);
//DROP(2) = 4;
newn.a = top.a;
newn.b = 0;
newn.way = 4;
Push(newn);
//POUR(1,2) = 5;
int tmp = m2 - top.b;
if(tmp <= top.a){
newn.a = top.a - tmp;
newn.b = m2;
}
else{
newn.a = 0;
newn.b = top.b + top.a;
}
newn.way = 5;
Push(newn);
//POUR(2,1) = 6;
tmp = m1 - top.a;
if(tmp <= top.b){
newn.a = m1;
newn.b = top.b - tmp;
}
else{
newn.a = top.a + top.b;
newn.b = 0;
}
newn.way = 6;
Push(newn);
}
if(k == -1)
printf("impossible\n");
}
}