广搜-nyoj-隐式图的搜索-三个水杯

来源:互联网 发布:主成分分析使用的数据 编辑:程序博客网 时间:2024/04/29 21:17

三个水杯

描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数N(0<N<50)表示N组测试数据
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
输出
每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1
样例输入
26 3 14 1 19 3 27 1 1
样例输出
3-1

下面的图引用了别人的点击打开链接,三个水杯间的倒水情况:




一个杯子,要么被倒满,要么倒完。自己的代码写得特麻烦,别人的好简单!!!!

#include<iostream>#include<cstdio>#include<map>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<cstdlib>#include<cctype>#include<cstring>#include<cmath>using namespace std;int vis[101][101][101];//记录是否被访问struct StateNode{    int cur[3];//记录水杯当前有多少水    int v[3];//记录水杯大小    int step;//步数};queue<StateNode> q;int Sucess(StateNode a,StateNode b){    //比较是否相等    return (a.cur[0] == b.cur[0] && a.cur[1] == b.cur[1] && a.cur[2] == b.cur[2]);}int main(){    int t,res;    StateNode b,e;      //e为需要的最终状态    cin>>t;    while(t--)    {        res=-1;        while(!q.empty()) //清空队列        {            q.pop();        }        cin>>b.v[0]>>b.v[1]>>b.v[2];        //下面开始模拟倒水,并搜索        b.cur[0]=b.v[0];//首先先给最大的水杯倒满水        b.cur[1]=b.cur[2]=0;//小杯子为0        b.step=0;//记录步数        cin>>e.cur[0]>>e.cur[1]>>e.cur[2];        int ok=0;//记录是否可以到达结尾状态        memset(vis,0,sizeof(vis));        q.push(b);//加入队列        vis[b.cur[0]][b.cur[1]][b.cur[2]]=1;//已经在访问或者已经访问        while(!q.empty()) //进行广搜        {            StateNode u=q.front();            //cout<<u.cur[0]<<" "<<u.cur[1]<<" "<<u.cur[2]<<endl;            q.pop();            if(Sucess(u,e)) //成功并结束            {                res=u.step;                break;            }            //else 模拟倒水            for(int i=0; i<=2; i++) //用每一个被子给其他两个被子倒水            {                for(int j=0; j<=2; j++)                {                    if(i!=j)                    {                        int minv=u.v[j]-u.cur[j];//从当前状态到被子倒满,需要的水                        if(u.cur[i]<minv) //当前的水小于需要的水,则能用的水变为当前的水                        {                            minv=u.cur[i];                        }                        //出现新节点                        StateNode v=u;                        v.cur[i]-=minv;//必须先减去                        v.cur[j]+=minv;                        v.step=u.step+1;//更新步数                        //cout<<u.step<<endl;                        if(!vis[v.cur[0]][v.cur[1]][v.cur[2]]) //该结点没有被访问                        {                            q.push(v);//加入队列                            vis[v.cur[0]][v.cur[1]][v.cur[2]]=1;//已访问                        }                    }                }            }        }        cout<<res<<endl;    }    return 0;}

以下是超长代码

 #include<stdio.h>#include<string.h>#include<queue>#include<math.h>using namespace std;int v1,v2,v3,e1,e2,e3,cnt,Max,flag;struct node{    int a,b,c,step;    bool operator <(const node &d)const    {        return d.step<step;    }};priority_queue<node> pq;int vis[105][105][105];void bfs(){    int i;    while(!pq.empty())    {        node t,t1;        t=pq.top();        pq.pop();        //getchar();        if(t.a==e1&&t.b==e2&&t.c==e3)        {            printf("%d\n",t.step);            return ;        }        if(t.a-(v2-t.b)>=0)        {            if(!vis[t.a-(v2-t.b)][v2][t.c])       //A把B装满            {                t1.a=t.a-(v2-t.b);                t1.b=v2;                t1.c=t.c;                vis[t.a-(v2-t.b)][v2][t.c]=1;                t1.step=t.step+1;                pq.push(t1);               // printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);            }        }        else if(!vis[0][t.b+t.a][t.c]&&t.b+t.a<=v2)       //把A倒完给B        {            t1.a=0;            t1.b=t.b+t.a;            t1.c=t.c;            vis[0][t.b+t.a][t.c]=1;            t1.step=t.step+1;            pq.push(t1);            //printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);        }        if(t.a-(v3-t.c)>=0)        {            if(!vis[t.a-(v3-t.c)][t.b][v3])     //A把C倒满            {                t1.a=t.a-(v3-t.c);                t1.b=t.b;                t1.c=v3;                vis[t.a-(v3-t.c)][t.b][v3]=1;                t1.step=t.step+1;                pq.push(t1);               // printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);            }        }        else if(!vis[0][t.b][t.a+t.c]&&t.a+t.c<=v3)     //把A倒完给C        {            t1.a=0;            t1.b=t.b;            t1.c=t.a+t.c;            vis[0][t.b][t.a+t.c]=1;            t1.step=t.step+1;            pq.push(t1);            //printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);        }        if(t.b-(v1-t.a)>=0)        {            if(!vis[v1][t.b-(v1-t.a)][t.c])    //B把A倒满            {                t1.a=v1;                t1.b=t.b-(v1-t.a);                t1.c=t.c;                vis[v1][t.b-(v1-t.a)][t.c]=1;                t1.step=t.step+1;                pq.push(t1);               // printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);            }        }        else if(!vis[t.a+t.b][0][t.c]&&t.a+t.b<=v1)     //把B倒完给A        {            t1.a=t.a+t.b;            t1.b=0;            t1.c=t.c;            vis[t.a+t.b][0][t.c]=1;            t1.step=t.step+1;            pq.push(t1);            //printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);        }        if(t.b-(v3-t.c)>=0)        {            if(!vis[t.a][t.b-(v3-t.c)][v3])    //B把C倒满            {                t1.a=t.a;                t1.b=t.b-(v3-t.c);                t1.c=v3;                vis[t.a][t.b-(v3-t.c)][v3]=1;                t1.step=t.step+1;                pq.push(t1);              //  printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);            }        }        else if(!vis[t.a][0][t.c+t.b]&&t.c+t.b<=v3)     //把B倒完给C        {            t1.a=t.a;            t1.b=0;            t1.c=t.c+t.b;            vis[t.a][0][t.c+t.b]=1;            t1.step=t.step+1;            pq.push(t1);            //printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);        }        if(t.c-(v1-t.a)>=0)        {            if(!vis[v1][t.b][t.c-(v1-t.a)])    //C把A倒满            {                t1.a=v1;                t1.b=t.b;                t1.c=t.c-(v1-t.a);                vis[v1][t.b][t.c-(v1-t.a)]=1;                t1.step=t.step+1;                pq.push(t1);               // printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);            }        }        else if(!vis[t.a+t.c][t.b][0]&&t.c+t.a<=v1)     //把C倒完给A        {            t1.a=t.a+t.c;            t1.b=t.b;            t1.c=0;            vis[t.a+t.c][0][0]=1;            t1.step=t.step+1;            pq.push(t1);           // printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);        }        if(t.c-(v2-t.b)>=0)        {            if(!vis[t.a][v2][t.c-(v2-t.b)])    //C把B倒满            {                t1.a=t.a;                t1.b=v2;                t1.c=t.c-(v2-t.b);                vis[t.a][v2][t.c-(v2-t.b)]=1;                t1.step=t.step+1;                pq.push(t1);              //  printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);            }        }        else if(!vis[t.a][t.b+t.c][0]&&t.c+t.b<=v2)     //把C倒完给B        {            t1.a=t.a;            t1.b=t.b+t.c;            t1.c=0;            vis[t.a][t.b+t.c][0]=1;            t1.step=t.step+1;            pq.push(t1);           // printf("%d %d %d %d\n",t1.a,t1.b,t1.c,t1.step);        }    }    flag=1;}int main(){    int n;    scanf("%d",&n);    while(n--)    {        memset(vis,0,sizeof(vis));        flag=0;        while(!pq.empty())            pq.pop();        node ss;        scanf("%d%d%d%d%d%d",&v1,&v2,&v3,&e1,&e2,&e3);        ss.step=0;        ss.a=v1;        ss.b=0;        ss.c=0;        vis[ss.a][0][0]=1;        pq.push(ss);        bfs();        if(flag==1)            printf("-1\n");    }    return 0;}        

0 0