程序设计思维与实践 Week2 作业 B - Pour Wate

题目描述:

倒水问题 "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列开始,不应该有空行或任何尾随空格。

思路:

这不是一道图论的题目,但是可以通过广度优先搜索的方法来解决。在已知当前A B两个杯子的状态后,可以选择下一个状态,但是下一个状态应该是之前没有出现过的,否则将进入死循环,这样没有任何意义。因此,广度优先搜索的思路就形成了,首先确定初始状态:A满B空或者A空B满,将两个状态分别进队,然后开始搜索即可,在出现A或B杯中的水量为C时,搜索停止。

搜索的具体过程:每次从队列取出一个结构体,当前结构体记录了此时A,B两个杯子的状态,对于A杯:1、判断是否可以将水倒入B中(条件是A不空且B不满),如果可以,则do!2、判断是否可以将A中的水倒掉(条件是A不空),如果可以,则do! 3、判断是否可以将A中到满水(条件是A不满),如果可以,则do! 对于B杯,同理与A杯。根据以上的规则,由当前的状态推出了下个状态,如果下个状态未出现过(由一个二维数组判断即可),则将其进队。当搜索到A或B杯中的水量为C时,搜索停止即可。

总结:

这是一道隐式图的问题,看似复杂,但可以通过广度优先搜索的方式,搜索枚举每个状态。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
bool flag[1010][1010];
int ansa[1010][1010],ansb[1010][1010],outa[10100],outb[10100],sum;
int A,B,C;
string s[5000];
struct node
{
	int a;
	int b;
}x;
queue<node> q;
void out()
{
	int a,b,nexta,nextb;
	for(int i=sum;i>1;i--)
	{
		if(i==sum)
		{
			if(outa[i]==A)
			cout<<"fill A"<<endl; 
			else
			cout<<"fill B"<<endl;
			//continue; 
		}
		a=outa[i],b=outb[i];
		nexta=outa[i-1],nextb=outb[i-1];
		if(nexta!=a&&nextb!=b)
		{
			if(nexta==0||nextb==B)
			cout<<"pour A B"<<endl;
			else cout<<"pour B A"<<endl;
		}
		else if(nexta==a&&nextb!=b)
		{
			if(nextb==0)
			cout<<"empty B"<<endl;
			else cout<<"fill B"<<endl;
		}
		else
		{
			if(nexta==0)
			cout<<"empty A"<<endl;
			else cout<<"fill A"<<endl;
		}
	}
	cout<<"success"<<endl;
}
void output(int a,int b)
{
	int lasta,lastb;sum=0;
	while(1)
	{
		int t=a;
		outa[++sum]=a;
		outb[sum]=b;
		a=ansa[a][b];
		b=ansb[t][b];//获取上次状态 
		if(a==A&&b==0)
		{
			outa[++sum]=A;
			outb[sum]=0;
			break;
		}
		if(a==0&&b==B)
		{
			outa[++sum]=0;
			outb[sum]=B;
			break;
		}
	}
	out();
}
void bfs()
{
	while(!q.empty()) q.pop();
	memset(ansa,0,sizeof(ansa)); 
	memset(ansb,0,sizeof(ansb)); 
	memset(flag,0,sizeof(flag));
	x.a=A;
	x.b=0;
	flag[A][0]=1;
	q.push(x);
	x.a=0;
	x.b=B;
	flag[0][B]=1;
	q.push(x);
	while(!q.empty())
	{
		int nowa=q.front().a;
		int nowb=q.front().b;
		q.pop();node tmp;
		if(nowa==C||nowb==C)
		{
			output(nowa,nowb);
			return;
		}
		if(nowa!=A)//a可以倒满 
		{
			tmp.a=A;tmp.b=nowb;
			if(!flag[tmp.a][tmp.b])
			{
				ansa[tmp.a][tmp.b]=nowa;
				ansb[tmp.a][tmp.b]=nowb;
				flag[tmp.a][tmp.b]=1;
				q.push(tmp);
			}
		}
		if(nowa!=A&&nowb>0)//b往a中倒
		{
			int cha=A-nowa;
			if(cha>nowb)//b倒入a且a还不满
			{
				tmp.a=nowa+nowb;
				tmp.b=0;
				if(!flag[tmp.a][tmp.b])
				{
					ansa[tmp.a][tmp.b]=nowa;
					ansb[tmp.a][tmp.b]=nowb;
					flag[tmp.a][tmp.b]=1;
					q.push(tmp);
				}
			}
			else//b倒入a,a满 
			{
				tmp.a=A;
				tmp.b=nowb-cha;
				if(!flag[tmp.a][tmp.b])
				{
					ansa[tmp.a][tmp.b]=nowa;
					ansb[tmp.a][tmp.b]=nowb;
					flag[tmp.a][tmp.b]=1;
					q.push(tmp);
				}
			}
		}
		if(nowb!=B)//将b倒满 
		{
			tmp.a=nowa;tmp.b=B;
			if(!flag[tmp.a][tmp.b])//将b倒满 
			{
				ansa[tmp.a][tmp.b]=nowa;
				ansb[tmp.a][tmp.b]=nowb;
				flag[tmp.a][tmp.b]=1;
				q.push(tmp);
			}
		}
		if(nowa>0&&nowb!=B)//a往b中倒 
		{
			int cha=B-nowb;
			if(nowa<cha)//a倒入b后,a空
			{
				tmp.a=0;
				tmp.b=nowb+nowa;
				if(!flag[tmp.a][tmp.b])
				{
					ansa[tmp.a][tmp.b]=nowa;
					ansb[tmp.a][tmp.b]=nowb;
					flag[tmp.a][tmp.b]=1;
					q.push(tmp);
				}
			}
			else//a倒入b后,b满 
			{
				tmp.a=nowa-cha;
				tmp.b=B;
				if(!flag[tmp.a][tmp.b])
				{
					ansa[tmp.a][tmp.b]=nowa;
					ansb[tmp.a][tmp.b]=nowb;
					flag[tmp.a][tmp.b]=1;
					q.push(tmp);
				}
			}
		}
		if(nowa>0)//a倒空 
		{
			tmp.a=0;tmp.b=nowb;
			if(!flag[tmp.a][tmp.b])
			{
				ansa[tmp.a][tmp.b]=nowa;
				ansb[tmp.a][tmp.b]=nowb;
				flag[tmp.a][tmp.b]=1;
				q.push(tmp);
			}
		}
		if(nowb>0)//b倒空 
		{
			tmp.a=nowa;tmp.b=0;
			if(!flag[tmp.a][tmp.b])
			{
				ansa[tmp.a][tmp.b]=nowa;
				ansb[tmp.a][tmp.b]=nowb;
				flag[tmp.a][tmp.b]=1;
				q.push(tmp);
			}
		}
	}
}
int main()
{
	while(scanf("%d%d%d",&A,&B,&C)!=EOF)
	{
		if(A==C)
		{
			cout<<"fill A"<<endl<<"success"<<endl;
			continue;
		}
		else if(B==C)
		{
			cout<<"fill B"<<endl<<"success"<<endl;
			continue;
		}
		bfs();
	}
}
发布了277 篇原创文章 · 获赞 222 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/cax1165/article/details/104583707
今日推荐