CSU - 2061 E - 迭代加深DFS/BFS

 
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

思路:本题的题意很简单了,给你三个杯子容量分别为x,y,z,开始的时候只有第一个杯子是满的,然后给你一个值d,因为杯子没有刻度所以杯子相互倒的时候只能给杯子倒满或者把自己这里的全倒进去,问能不能在这个过程中有杯子里面的咖啡有dml。

这题是一道迭代加深的bfs,因为x,y,z都小于1000,所以不管怎么倒最后得到的状态不会超过1000000种,那么我们就深搜完所有的情况就可以了,我们利用struct结构体来存储状态,一个状态就是当时的三个杯子对应的容量,id就是这个是第几个的状态,每一个状态最多会生成多少种状态呢,我们考虑第一个杯子,我们假设第一个杯子有咖啡的话,它能往第二个杯子里到也能往第三个杯子里倒,以第二个杯子为例,第一个杯子倒第二个杯子,因为倒只能把杯子倒满或者自身全倒完,所以就是两种情况,倒进来第二个杯子容量不够,这时候第一个杯子还剩temp.a+temp.b-y,也就是第二个杯子满了,第一个杯子还剩,第二种情况就是第一个杯子倒完了,第二个杯子有temp.a+temp.b。同样第一个杯子倒第三个杯子也是2种。

这样的话一个杯子倒有四种,那么一个状态三个杯子就是12种,我们把这12种列出来加到队列里面。

那么这时候就有问题了,我倒过来别人倒进去,不就重复了吗,所以我们利用vis数组记录,因为总值不变,所以只需要记录第一个杯子和第二个杯子的容量就能代表那个状态是否出现过,我们在把下一个状态想放到队列里判断的时候就要加上去这个状态是否出现了也就是temp.b+temp.a<=y&&vis[0][temp.a+temp.b]==0。

还有就是我们还需要确定路径我们利用fa数组,我们已经利用了id记录状态的数量,所以一次变化,引出的状态父亲都是temp.id。

最后输出就根据fa一个个往前推输出就可以了。

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
using namespace std;

typedef long long LL;
const int maxn=1005;
int T,x,y,z,d;
int vis[maxn][maxn];
int cnt;
struct Node
{
    int a,b,c;
    int id;
}node[1000005];
int fa[1000005];
queue<Node>q;
stack<Node>ss;

void init()
{
    while(!q.empty())
        q.pop();
    memset(vis,0,sizeof(vis));
    cnt=1;
}
void coutfun(int i)
{
    int ans=0;
    while(fa[i]!=0)
    {
        ans++;
        //cout<<node[i].a<<" "<<node[i].b<<" "<<node[i].c<<endl;
        ss.push(node[i]);
        i=fa[i];
    }
    cout<<ans<<endl;
    cout<<x<<" "<<"0"<<" "<<"0"<<endl;
    while(!ss.empty())
    {
        cout<<ss.top().a<<" "<<ss.top().b<<" "<<ss.top().c<<endl;
        ss.pop();
    }
}
void bfs()
{
    Node temp,next;
    while(!q.empty())
    {
        temp=q.front();
        int c1=temp.id;
        //cout<<c1<<endl;
        q.pop();
        //cout<<temp.a<<" "<<temp.b<<" "<<temp.c<<endl;
        if(temp.a==d||temp.b==d||temp.c==d)
        {
            coutfun(c1);
            return;
        }
        else
        {
            if(temp.a!=0)
            {
                if(temp.b+temp.a<=y&&vis[0][temp.a+temp.b]==0)
                {
                    cnt++;
                    node[cnt].a=0;node[cnt].b=temp.a+temp.b;node[cnt].c=temp.c;node[cnt].id=cnt;
                    vis[0][temp.a+temp.b]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                   // cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.c+temp.a<=z&&vis[0][temp.b]==0)
                {
                    cnt++;
                    node[cnt].a=0;node[cnt].b=temp.b;node[cnt].c=temp.c+temp.a;node[cnt].id=cnt;
                    vis[0][temp.b]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.b+temp.a>y&&vis[temp.a+temp.b-y][y]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a+temp.b-y;node[cnt].b=y;node[cnt].c=temp.c;node[cnt].id=cnt;
                    vis[temp.a+temp.b-y][y]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.c+temp.a>z&&vis[temp.a+temp.c-z][temp.b]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a+temp.c-z;node[cnt].b=temp.b;node[cnt].c=z;node[cnt].id=cnt;
                    vis[temp.a+temp.c-z][temp.b]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
            }
            if(temp.b!=0)
            {
                if(temp.b+temp.a<=x&&vis[temp.a+temp.b][0]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a+temp.b;node[cnt].b=0;node[cnt].c=temp.c;node[cnt].id=cnt;
                    vis[temp.a+temp.b][0]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.c+temp.b<=z&&vis[temp.a][0]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a;node[cnt].b=0;node[cnt].c=temp.c+temp.b;node[cnt].id=cnt;
                    vis[temp.a][0]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                   // cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.b+temp.a>x&&vis[x][temp.a+temp.b-x]==0)
                {
                    cnt++;
                    node[cnt].a=x;node[cnt].b=temp.a+temp.b-x;node[cnt].c=temp.c;node[cnt].id=cnt;
                    vis[x][temp.a+temp.b-x]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.c+temp.b>z&&vis[temp.a][temp.c+temp.b-z]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a;node[cnt].b=temp.c+temp.b-z;node[cnt].c=z;node[cnt].id=cnt;
                    vis[temp.a][temp.c+temp.b-z]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
            }
            if(temp.c!=0)
            {
                if(temp.b+temp.c<=y&&vis[temp.a][temp.b+temp.c]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a;node[cnt].b=temp.c+temp.b;node[cnt].c=0;node[cnt].id=cnt;
                    vis[temp.a][temp.b+temp.c]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.c+temp.a<=x&&vis[temp.a+temp.c][temp.b]==0)
                {
                    cnt++;
                    node[cnt].a=temp.c+temp.a;node[cnt].b=temp.b;node[cnt].c=0;node[cnt].id=cnt;
                    vis[temp.a+temp.c][temp.b]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.b+temp.c>y&&vis[temp.a][y]==0)
                {
                    cnt++;
                    node[cnt].a=temp.a;node[cnt].b=y;node[cnt].c=temp.c+temp.b-y;node[cnt].id=cnt;
                    vis[temp.a][y]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                   // cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
                if(temp.c+temp.a>x&&vis[x][temp.b]==0)
                {
                    cnt++;
                    node[cnt].a=x;node[cnt].b=temp.b;node[cnt].c=temp.c+temp.a-x;node[cnt].id=cnt;
                    vis[x][temp.b]=1;
                    fa[cnt]=c1;
                    q.push(node[cnt]);
                    //cout<<node[cnt].a<<" "<<node[cnt].b<<" "<<node[cnt].c<<endl;
                }
            }
        }
    }
    cout<<"-1"<<endl;
}

int main()
{
    cin>>T;
    while(T--)
    {
        init();
        cin>>x>>y>>z>>d;
        node[1].a=x;node[1].b=0;node[1].c=0;node[1].id=1;
        q.push(node[1]);
        vis[x][y]=1;
        bfs();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Abandoninged/article/details/81257019