题意:有两个有瓶子,容量给定,初始为空。有六个动作可以选择。求如何使得某个瓶子中剩下给定量的油。六个动作及相应序号如下:
1 fill A
2 fill B
3 empty A
4 empty B
5 pour A to B
6 pour B to A
思路:BFS。队列存放两个瓶子的油量以及得到此状态的前一状态在队列中的位置。flag[i][j]为得到AB瓶容量分别为i和j所做的动作序号。
#include <stdio.h>
#include <string.h>
#define N 1002
char output[7][10] = {"","fill A","fill B",
"empty A","empty B",
"pour A B","pour B A"};
int a,b,res,flag[N][N],q[N*N][3];
void print(int index){
int i;
if(index != 0){
print(q[index][2]);//递归输出前1动作
printf("%s\n",output[flag[q[index][0]][q[index][1]]]);
}
}
void bfs(){
int x,y,front,rear;
front = rear = -1;
q[++rear][0] = 0;
q[rear][1] = 0;
q[rear][2] = -1;
while(front < rear){
x = q[++front][0];
y = q[front][1];
if(x == res || y == res){
print(front);
return ;
}
if(x<a && !flag[a][y]){//动作1
flag[a][y] = 1;
q[++rear][0] = a;
q[rear][1] = y;
q[rear][2] = front;
}
if(y<b && !flag[x][b]){//动作2
flag[x][b] = 2;
q[++rear][0] = x;
q[rear][1] = b;
q[rear][2] = front;
}
if(x && !flag[0][y]){//动作3
flag[0][y] = 3;
q[++rear][0] = 0;
q[rear][1] = y;
q[rear][2] = front;
}
if(y && !flag[x][0]){//动作4
flag[x][0] = 4;
q[++rear][0] = x;
q[rear][1] = 0;
q[rear][2] = front;
}
if(x && y<b){//动作5
if(x <= b-y && !flag[0][y+x]){
flag[0][y+x] = 5;
q[++rear][0] = 0;
q[rear][1] = y+x;
q[rear][2] = front;
}
if(x > b-y &&!flag[x-b+y][b]){
flag[x-b+y][b] = 5;
q[++rear][0] = x-b+y;
q[rear][1] = b;
q[rear][2] = front;
}
}
if(x<a && y){//动作6
if(y <= a-x && !flag[x+y][0]){
flag[x+y][0] = 6;
q[++rear][0] = x+y;
q[rear][1] = 0;
q[rear][2] = front;
}
if(y > a-x && !flag[a][y-a+x]){
flag[a][y-a+x] = 6;
q[++rear][0] = a;
q[rear][1] = y-a+x;
q[rear][2] = front;
}
}
}
}
int main(){int i;
freopen("a.txt","r",stdin);
while(scanf("%d %d %d",&a,&b,&res)!=EOF){
int i,j;
memset(flag,0,sizeof(flag));
flag[0][0] = -1;
bfs();
printf("success\n");
}
return 0;
}
本文介绍了一种使用广度优先搜索(BFS)算法解决特定倒油问题的方法。该问题涉及两个不同容量的瓶子,目标是通过一系列操作使其中一个瓶子恰好包含给定数量的液体。文章详细展示了算法实现步骤,并提供了完整的C语言代码示例。

被折叠的 条评论
为什么被折叠?



