poj 1606 bfs(倒油)

题意:有两个有瓶子,容量给定,初始为空。有六个动作可以选择。求如何使得某个瓶子中剩下给定量的油。六个动作及相应序号如下:

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值