2061: Z‘s Coffee(bfs或dfs+记录路径)

2061: Z‘s Coffee

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2061

Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 120     Solved: 40     SpecialJudge


Description

 
Z is crazy about coffee. One day he bought three cups of coffee. The first cup has a capacity of Aml, the second has Bml and the third has Cml. At the beginning, only the first cup is full of coffee, that is, Z only has Aml coffee and the other cups is empty. Because the cup has no scale, one operation of pouring coffee only stop until either one cup is full or empty. Z can only choose two cups to do the pouring operation. For some reasons, Z wants to get exactly Dml of coffee, and also he is so lazy that want the number of operations as least as possible. So he ask you for help.

Input

The first line is the case number T.

Each case has one line with four integers ABCD as mentioned above.

1 ≤ A, B, C ≤ 1000

1 ≤ D ≤ max(A, B, C)

1 ≤ T ≤ 100

Output

If he can get the exactly milliliter of coffee as he want, then print the least number of operation in a line.

And print the initial capacity of the three cups and then print the result after each operation line by line.

The print order should be the first cup, the second cup and the third cup.

If there are more than one operation schema, any of them will be accepted.

If he cannot get the exactly milliliter of coffee as he want , print "-1" without quotation.

Sample Input

1
12 8 5 10

Sample Output

5
12 0 0
7 0 5
0 7 5
5 7 0
5 2 5
10 2 0

Hint

Source

Author

周杰辉

dfs或者bfs均可。具体方法是对每次操作分成a,c向b倒,a,b向c倒,b,c向a倒。六种情况,再对三个杯子中的咖啡量进行记录,如不重复则继续迭代加深,直至全部搜完,或者搜出答案。这里有一个问题,用bfs可以比较容易得搜索出最快的方法的结果,用dfs可以较方便得记录倒的方法。但是为了同时得到最短的次数和记录的方法,使用dfs时需要记录可以达成的最少次数,并对每一种方法作记录最终输出次数最少的那个。bfs相对 简单,只需要记录某一次操作的上一次操作是什么即可,在最后得到最后一步后再向前回溯,详情见代码(BFS):

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
struct node{
	int xx,yy,zz;
	int pre;
	node(int x,int y,int z,int id)
	{
		xx=x;yy=y;zz=z;pre=id;
	}
	node()
	{
	}
};
queue<node> q;
vector<node> v;
int a,b,c,d;
int ori[3];
int flag[1001][1001];
int mov[6][3]={{2,0,0},{1,0,0},{0,1,1},{2,1,1},{0,2,2},{1,2,2}};
inline void coll(int &acc,int &by,int vol)
{
	//cout<<acc<<' '<<by<<' '<<vol<<endl;
	if(acc+by>=vol)  
	{
		acc=acc-(vol-by);
		by=vol;
		//cout<<acc<<endl;
		return;
	}
	else if(acc+by<vol)
	{
		by+=acc;
		acc=0;
		
		return;
	}
}
node u;
int bfs(int x,int y,int z)
{
	while(!q.empty()) q.pop();
	node temp(x,y,z,0);
	q.push(temp);
	flag[x][y]=1;
	int date[3];
	while(!q.empty())
	{
		u=q.front();
		q.pop();
		v.push_back(u);
		if(u.xx==d||u.yy==d||u.zz==d)
		{
			return 1;
		}
		else
		{
			for(int i=0;i<6;i++)
			{
				date[0]=u.xx;date[1]=u.yy;date[2]=u.zz;
				coll(date[mov[i][0]],date[mov[i][1]],ori[mov[i][2]]);
				node l(date[0],date[1],date[2],v.size()-1);
				if(!flag[l.xx][l.yy]) 
				{
					//cout<<u.xx<<' '<<u.yy<<' '<<u.zz<<endl;
					//cout<<i<<endl;
					//
					
					flag[l.xx][l.yy]=1;
					q.push(l);
					
				}
			}
		}
	}
	return -1;
}
int roar[1000000];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		while(!v.empty()) v.pop_back();
		memset(flag,0,sizeof(flag));
		cin>>a>>b>>c>>d;
		ori[0]=a;ori[1]=b;ori[2]=c;
		if(bfs(a,0,0)==-1)
		cout<<"-1"<<endl;
		else
		{
			int cnt=0;
			int i;
			for(i=v.size()-1;i!=0;i=v[i].pre)
			{
				//printf("%d %d %d\n",v[i].xx,v[i].yy,v[i].zz);
				roar[cnt++]=i;
			}
			printf("%d\n",cnt);
			printf("%d %d %d\n",a,0,0);
			for(int i=cnt-1;i>=0;i--)
			{
				printf("%d %d %d\n",v[roar[i]].xx,v[roar[i]].yy,v[roar[i]].zz);
			}
		}
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值