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 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
周杰辉
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;
}