Week2 作业B - Pour Water

题目描述

倒水问题 “fill A” 表示倒满A杯,"empty A"表示倒空A杯,“pour A B” 表示把A的水倒到B杯并且把B杯倒满或A倒空。

Input

输入包含多组数据。每组数据输入 A, B, C 数据范围 0 < A <= B 、C <= B <=1000 、A和B互质。

Output

你的程序的输出将由一系列的指令组成。这些输出行将导致任何一个罐子正好包含C单位的水。每组数据的最后一行输出应该是“success”。输出行从第1列开始,不应该有空行或任何尾随空格。

Sample Input

2 7 5
2 7 4

Sample Output

fill B
pour B A
success 
fill A
pour A B
fill A
pour A B
success

解题思路

用结构体记录各个状态,分别为a中的水,b中的水,还有上一个状态,上一个状态进行的操作。
用bfs遍历,每个状态有六条“路”,分别为a倒空,b倒空,a倒满,b倒满,a倒入b,b倒入a。每次判断一下两个杯子中的水量是否为c,是则输出,不是则继续。(数据量较大,用数组没有扩容函数则会runtime error)

完整代码

//用bfs遍历各种情况,分别为a倒空,b倒空,a倒满,b倒满,a倒入b,b倒入a
//用新的结构体记录各个状态,分别为a中的水,b中的水,还有上一个状态。
//每次判断一下两个杯子中的水量是否为c
//preaction:1表示empty A;2表示empty B;3表示fill A;4表示fill B;5表示pour A B;6表示pour B A; 
#include<iostream>
using namespace std;

struct State{
	int a;
	int b;
	int pre;
	int preaction;

};

void changeLength1D(State*& a, int oldLength, int newLength)
{
   State* temp = new State[newLength];              // new array
   int number = min(oldLength, newLength);  // number to copy
   copy(a, a + number, temp);
   delete [] a;                             // deallocate old memory
   a = temp;
}

int bfs(int A,int B,int C)
{
 State *state=new State[100];//队列
 int size=100;
 int out[200];
 int front=0;
 state[0].a=0;
 state[0].b=0;
 int end=1; 
 
 	while(front!=end)//即队列不空
		{if(end>size-10)
	{	changeLength1D(state,size,2*size);
	size=2*size;}
		//判断6种状态是否有相等的 
		
		//1.a中倒空 
		if(state[front].a>0)
			{//cout<<"1"<<endl;
			//cout<<"a: "<<state[front].a<<" b: "<<state[front].b<<endl;
			state[end].a=0;
			state[end].b=state[front].b;
			state[end].pre=front;
			state[end].preaction=1;
			end++;}
	
		//2.b中倒空 		
		if(state[front].b>0)
			{//cout<<"2"<<endl;
			//cout<<"a: "<<state[front].a<<" b: "<<state[front].b<<endl;
			state[end].b=0;
			state[end].a=state[front].a;
			state[end].pre=front;
			state[end].preaction=2;
			end++;}
			
		//3.a中倒满
		if(state[front].a<A)
		{//cout<<"3"<<endl;
		//cout<<"a: "<<state[front].a<<" b: "<<state[front].b<<endl;	
			state[end].a=A;
			state[end].b=state[front].b;
			state[end].pre=front;
			state[end].preaction=3;
			
			if(state[end].a==C)
			break;
			
			end++;}	 
			
		//4.b中倒满
		if(state[front].b<B)
		{	//cout<<"4"<<endl;
	//	cout<<"a: "<<state[front].a<<" b: "<<state[front].b<<endl;
			state[end].b=B;
			state[end].a=state[front].a;
			state[end].pre=front;
			state[end].preaction=4;
			
		if(state[end].b==C)
			break;
			
			end++;}	 
			
		//5.a倒入b(判断a中是否剩余,b是否倒满,再判断当前状态是否能出现C)		
		if(state[front].a>0&&state[front].b!=B)
		{//cout<<"5"<<endl;
		//cout<<"a: "<<state[front].a<<" b: "<<state[front].b<<endl;
		if(state[front].a>B-state[front].b)//a中有剩余且b满了
			{state[end].a=state[front].a-B+state[front].b;
			 state[end].b=B;
			 state[end].pre=front;
			 state[end].preaction=5;
			if(state[end].a==C)//success,输出 
				break;
			end++;} 
				
		else//a中没有剩余,b中满不满不确定
			{state[end].b=state[front].a+state[front].b;
			 state[end].a=0;
			 state[end].pre=front;
			 state[end].preaction=5;
			 if(state[end].b==C)//success,输出
				break;
			end++; 
		
		}
		} 
		
		
		//6.b倒入a(判断b中是否剩余,a是否倒满,再判断当前状态是否能出现C)		
		if(state[front].b>0&&state[front].a!=A) 
		{//cout<<"6"<<endl;
	//	cout<<"a: "<<state[front].a<<" b: "<<state[front].b<<endl;
		if(state[front].b>A-state[front].a)//b中有剩余且a满了
			{state[end].b=state[front].b-A+state[front].a;
			 state[end].a=A;
			 state[end].pre=front;
			 state[end].preaction=6;
			if(state[end].b==C)//success,输出 
				break;
			end++;} 
				
		else//b中没有剩余,a中满不满不确定
			{state[end].a=state[front].a+state[front].b;
			 state[end].b=0;
			 state[end].pre=front;
			 state[end].preaction=6;
			 if(state[end].a==C)//success,输出
				break;
			end++; 
		
		}
		} 
		
		
		front++;
		}

				int i=0;
				int pre=state[end].pre;
				int preaction=state[end].preaction;
				while(pre!=0)
				{out[i]=preaction;
				preaction=state[pre].preaction;
				pre=state[pre].pre;
				i++;
				}
				out[i]=preaction;
			for(int m=i;m>=0;m--)
				{switch (out[m]){
					case 1:
						cout<<"empty A"<<endl;
						break;
					case 2:
						cout<<"empty B"<<endl;
						break;
					case 3:
						cout<<"fill A"<<endl;
						break;
					case 4:
						cout<<"fill B"<<endl;
						break;
					case 5:
						cout<<"pour A B"<<endl;
						break;
					case 6:
						cout<<"pour B A"<<endl;
						break;
					}
				}cout<<"success"<<endl;
				




}
int main(){
	int a,b,c;
	while(cin>>a>>b>>c)
	bfs(a,b,c);
} 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值