CSU - 2061 Z‘s Coffee

Description


Z is crazy about coffee. One day he bought three cups of coffee. The first cup has a capacity of A ml, the second has B ml and the third has C ml. At the beginning, only the first cup is full of coffee, that is, Z only has A ml 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 D ml 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 A B C D 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

周杰辉

设当前每杯的容量为 x, y, z , 因为 x + y + z = A 则可以枚举 i, j ,将第 i 杯中的咖啡倒入第 j 杯 如果满足条件,设倒入后的状态为 x′,y′,z′ 判断其中是否有 D ,并记录其前驱 为保证操作最少,用 BFS 扩展即可
#include<stdio.h>
#include<queue>
#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 1e6 + 5;
struct node{
	int cup[3],stp;
	int hash(){ return cup[0] * 1001 * 1001 + cup[1] * 1001 + cup[2]; }
	void print(){ printf("%d %d %d\n", cup[0], cup[1], cup[2]); }
};
queue<node>q;
set<int>se;
vector<node>ve;
node Q[MAXN];
int pre[MAXN];
int cup[3], d;
int bfs()
{
	int l = 0,r=0;
	node tmp;
	tmp.cup[0] = cup[0]; tmp.cup[1] = tmp.cup[2]=tmp.stp = 0;
	Q[++r] = tmp;
	se.insert(tmp.hash());
	while (l<r)
	{
		node u = Q[++l];
		for (int i = 0; i < 3;i++)
			if (u.cup[i])//对每个杯子
			{
				for (int j = 0; j < 3;j++)
					if (i != j&&u.cup[j] != cup[j])//不同杯子 也没有满
					{
						node v = u;
						if (v.cup[i] + v.cup[j]>cup[j])
						{
							v.cup[i] = v.cup[i] - (cup[j] - v.cup[j]);
							v.cup[j] = cup[j];
						}
						else
						{
							v.cup[j] += v.cup[i];
							v.cup[i] = 0;
						}
						v.stp = u.stp + 1;
						int hash = v.hash();
						if (!se.count(hash))//记录是否出现过该情况
						{
							se.insert(hash);
							Q[++r] = v;
							pre[r] = l;
							for (int k = 0; k < 3; k++)
							{
								if (v.cup[k] == d)return r;
							}
						}
					}
			}
	}
	return -1;
}
int main()
{
	int T;
	while (~scanf("%d", &T))
	{
		while (T--)
		{
			while (!q.empty())
				q. pop();
			scanf("%d %d %d %d", &cup[0], &cup[1], &cup[2],&d);
			se.clear();
			int ans = bfs();
			if (ans == -1)
			{
				printf("-1\n");
				continue;
			}
			int cnt = Q[ans].stp;
			ve.clear();
			for (int i = ans; i; i = pre[i])
				ve.push_back(Q[i]);
			reverse(ve.begin(), ve.end());
			printf("%d\n", cnt);
			for (int i = 0; i < ve.size(); i++)
			{
				printf("%d %d %d\n", ve[i].cup[0], ve[i].cup[1], ve[i].cup[2]);
			}
		}
	}

	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值