Pots 用bfs模拟2杯子体积分别为A,B通过一系列操作把其中一杯子变为C升水

Pots POJ - 3414
给你两个罐子,

分别有A升和B升的体积
这里开始的时候A和B的杯子都是没有水的

。可以执行以下操作:

1,FILL(i)从水龙头填充锅i (1 ≤ i ≤ 2);
2,DROP(i) 将锅i排空至排水管;
3,POUR(i,j) 从锅i倒入锅j;在此操作之后,要么锅j已满(锅i 中可能还有一些水),要么锅i是空的(并且其所有内容都已移到锅j 中)

编写一个程序,找出这些操作的最短可能序列以便在其中一个锅中产生恰好C升的水

输入
第一行也是唯一一行是数字A、B和C。这些都是 1 到 100 范围内的整数,并且C ≤max( A , B )。

输出
输出的第一行必须包含操作序列K的长度。以下K行必须每行描述一个操作。如果有几个最小长度的序列,输出其中的任何一个。如果无法达到预期的结果,文件的第一行也是唯一的一行必须包含单词“impossible”。

Inpput
3 5 4

Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
思路:看到题目的最短操作用bfs模拟;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int vist[110][110];//保存的是A和B的量是否标记过 
int A,B,C,flag,o;
string work[10]= {"","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};//走相应的操作 
struct node {
	int x;
	int y;
	int step;//几步 
	string s;//对应work的数字 
};
queue<node> q;
void bfs() {
	q.push({0,0,0,"0"});
	vist[0][0]=1;
	while(!q.empty()) {
		node H=q.front();
		q.pop();
		if(H.x==C||H.y==C){// A或B有其中一个产生C量的水,则立刻输出步数 
			cout<<H.step<<endl;
			for(int i=1;i<H.s.size();i++){//输出对应的步骤 
				cout<<work[H.s[i]-'0']<<endl;
			}
			flag=1;//标记成功 
			return ;
		}
		//下面对应着6个操作,每个都来,操作的时候考虑实际状况,比如是否满了;或者是否清空没有了 
		if(H.x<A&&(!vist[A][H.y])) {  //FILL(1)
			vist[A][H.y]=1;
			q.push({A,H.y,H.step+1,H.s+"1"});
		}
		if(H.y<B&&(!vist[H.x][B])) { //FILL(2)
			vist[H.x][B]=1;
			q.push({H.x,B,H.step+1,H.s+"2"});
		}
		if(H.x>0&&(!vist[0][H.y])) {   //DROP(1)
			vist[0][H.y]=1;
			q.push({0,H.y,H.step+1,H.s+"3"});
		}
		if(H.y>0&&(!vist[H.x][0])) {  //DROP(2)
			vist[H.x][0]=1;
			q.push({H.x,0,H.step+1,H.s+"4"});
		}
		if(H.x!=0&&H.y<B) {  //POUR(1,2)
			int nx,ny;
			if(H.x+H.y<=B) {
				ny=H.x+H.y;
				nx=0;
			} else {
				nx=H.x+H.y-B;
				ny=B;
			}
			if(!vist[nx][ny]) {
				vist[nx][ny]=1;
				q.push({nx,ny,H.step+1,H.s+"5"});
			}
		}
		if(H.y!=0&&H.x<A){  //POUR(2,1)
			int nx,ny;
			if(H.x+H.y<=A){
				nx=H.x+H.y;
				ny=0;
			}
			else{
				nx=A;
				ny=H.x+H.y-A;
			}
			if(!vist[nx][ny]){
				vist[nx][ny]=1;
				q.push({nx,ny,H.step+1,H.s+"6"});
			}
		}
	}
		
}
int main() {

	while(~scanf("%d%d%d",&A,&B,&C)) {
		flag=0;
		bfs();
		if(!flag){
			printf("impossible\n");//没有则输出 impossible
		}
	}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值