POJ3414--Pots

Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤ i ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input

3 5 4

Sample Output

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
/*
C<=max(a,b)....
a,b,c上限是100
每一次可以进行六种操作:
一:装满A 二:装满B
三:倒掉A 四:倒掉B
五:A倒B  六:B倒A
判断是否达到目标的条件:
在队列首判断va或者vb。如果等就可以退出队列了(原先我一直以为可以va+vb==c)贡献若干个WA
至于要输出过程嘛。可以用一个结构体来存。
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <string>
using namespace std;
#define maxn 108
#define inf 0x3f3f3f3f
int dis[maxn][maxn];
string A[maxn*maxn];
struct PRE
{
	int prea,preb;
	bool fill;
	bool drop;
	bool pour;
	int v1,v2;//如果只需要用到一个的时候就直接用
}pre[maxn][maxn];//pre[a][b]用来存第一个罐子的水量为a,第二个罐子的水量为b的前驱
inline int man(int a,int b)
{
	return a>b?a:b;
}
int main()
{
	int a,b,c;//a,b分别是容量,c=是要装出来的
	while(scanf("%d%d%d",&a,&b,&c)==3)
	{
		bool flag=false;
		memset(dis,0x3f,sizeof(dis));
		int mab=max(a,b);
		for(int i=0;i<=mab;i++)
		{
			for(int j=0;j<=mab;j++)
			{
				dis[i][j]=inf;
				pre[i][j].drop=pre[i][j].fill=pre[i][j].pour=0;
			}
		}
		dis[0][0]=0;
		queue <int> qa;
		queue <int> qb;
		qa.push(0);
		qb.push(0);
		int ta,tb;
		while(!qa.empty())
		{
			int va=qa.front();
			int vb=qb.front();
			qa.pop();qb.pop();
			if(va==c||vb==c)
			{
				ta=va;tb=vb;
				flag=true;
				break;
			}
			//操作一:fill a
			if(dis[va][vb]+1<dis[a][vb])
			{
				dis[a][vb]=dis[va][vb]+1;
				pre[a][vb].fill=true;
				pre[a][vb].drop=pre[a][vb].pour=false;
				pre[a][vb].v1=1;
				pre[a][vb].prea=va;
				pre[a][vb].preb=vb;
				qa.push(a);
				qb.push(vb);
			}
			//操作二:fill b
			if(dis[va][vb]+1<dis[va][b])
			{
				dis[va][b]=dis[va][vb]+1;
				pre[va][b].fill=true;
				pre[va][b].pour=pre[va][b].drop=false;
				pre[va][b].v1=2;
				pre[va][b].prea=va;
				pre[va][b].preb=vb;
				qa.push(va);
				qb.push(b);
			}
			//操作三:倒掉 a
			if(dis[va][vb]+1<dis[0][vb])
			{
				dis[0][vb]=dis[va][vb]+1;
				pre[0][vb].drop=true;
				pre[0][vb].fill=pre[0][vb].pour=false;
				pre[0][vb].v1=1;
				pre[0][vb].prea=va;
				pre[0][vb].preb=vb;
				qa.push(0);
				qb.push(vb);
			}
			//操作四:倒掉 b
			if(dis[va][vb]+1<dis[va][0])
			{
				dis[va][0]=dis[va][vb]+1;
				pre[va][0].drop=true;
				pre[va][0].fill=pre[va][0].pour=false;
				pre[va][0].v1=2;
				pre[va][0].prea=va;
				pre[va][0].preb=vb;
				qa.push(va);
				qb.push(0);
			}
			//操作五: a倒入b
			if(va+vb<=b&&dis[va][vb]+1<dis[0][va+vb])
			{
				dis[0][va+vb]=dis[va][vb]+1;
				pre[0][va+vb].pour=true;
				pre[0][va+vb].fill=pre[0][va+vb].drop=false;
				pre[0][va+vb].v1=1;
				pre[0][va+vb].v2=2;
				pre[0][va+vb].prea=va;
				pre[0][va+vb].preb=vb;
				qa.push(0);
				qb.push(va+vb);
			}
			if(va+vb>b&&dis[va][vb]+1<dis[va+vb-b][b])
			{
				dis[va+vb-b][b]=dis[va][vb]+1;
				pre[va+vb-b][b].pour=true;
				pre[va+vb-b][b].fill=pre[va+vb-b][b].drop=false;
				pre[va+vb-b][b].v1=1;
				pre[va+vb-b][b].v2=2;
				pre[va+vb-b][b].prea=va;
				pre[va+vb-b][b].preb=vb;
				qa.push(va+vb-b);
				qb.push(b);
			}
			//操作六: b倒入a
			if(va+vb<=a&&dis[va][vb]+1<dis[va+vb][0])
			{
				dis[va+vb][0]=dis[va][vb]+1;
				pre[va+vb][0].pour=true;
				pre[va+vb][0].fill=pre[va+vb][0].drop=false;
				pre[va+vb][0].v1=2;
				pre[va+vb][0].v2=1;
				pre[va+vb][0].prea=va;
				pre[va+vb][0].preb=vb;
				qa.push(va+vb);
				qb.push(0);
			}
			if(va+vb>a&&dis[va][vb]+1<dis[a][va+vb-a])
			{
				dis[a][va+vb-a]=dis[va][vb]+1;
				pre[a][va+vb-a].pour=true;
				pre[a][va+vb-a].fill=pre[a][va+vb-a].drop=false;
				pre[a][va+vb-a].v1=2;
				pre[a][va+vb-a].v2=1;
				pre[a][va+vb-a].prea=va;
				pre[a][va+vb-a].preb=vb;
				qa.push(a);
				qb.push(va+vb-a);
			}
		}
		if(!flag) cout<<"impossible"<<endl;
		else
		{
			cout<<dis[ta][tb]<<endl;
			//ta tb
			int sum=dis[ta][tb];
			int fuck=sum;
			int ia=ta,ib=tb;
			while(1)
			{
				if(ia==0&&ib==0) break;
				if(pre[ia][ib].fill)
				{
					A[fuck]="FILL(";
					A[fuck].push_back('0'+pre[ia][ib].v1);
					A[fuck].push_back(')');
					fuck--;
				}
				if(pre[ia][ib].drop)
				{
					A[fuck]="DROP(";
					A[fuck].push_back('0'+pre[ia][ib].v1);
					A[fuck].push_back(')');
					fuck--;
				}
				if(pre[ia][ib].pour)
				{
					A[fuck]="POUR(";
					A[fuck].push_back('0'+pre[ia][ib].v1);
					A[fuck].push_back(',');
					A[fuck].push_back('0'+pre[ia][ib].v2);
					A[fuck].push_back(')');
					fuck--;
				}
				int iia=ia,iib=ib;
				ia=pre[iia][iib].prea;
				ib=pre[iia][iib].preb;
			}
			for(int i=1;i<=sum;i++)
			{
				cout<<A[i]<<endl;
			}
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值