小白书之隐式图的bfs

来源:互联网 发布:麒麟linux官网 编辑:程序博客网 时间:2024/06/13 23:26

可以把三杯水各个时候的状态想象成一个点,能到达的点画一条有向边,这样就出现一个图,对这张图进行dfs,

这里注意要用一个set去掉重复的状态,以免陷入死循环。同时这题用一个数组同时存储了三个杯子的状态并且

顺带储存了父亲节点的状态,比较巧妙,但是好像一般bfs都是手写的队列,但是我习惯了用queue容器。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<string>#include<algorithm>#include<map>#include<set>#include<vector>#include<stack>#include<queue>#include<climits>using namespace std;const int N=1e6+10;int st[N][4];int cup[3];int x;set<int> vis;int water(int l,int m,int *buf){    if(buf[l]!=0&&buf[m]!=cup[m])    {        if(buf[l]+buf[m]<=cup[m])        {            buf[m]+=buf[l];            buf[l]=0;            return 1;        }        else        {            buf[l]=buf[l]-(cup[m]-buf[m]);            buf[m]=cup[m];            return 1;        }    }    return 0;}int insert(int *buf){    int v=0;    for(int i=0;i<3;i++)        v=v*10+buf[i];    if(vis.count(v)) return 0;    vis.insert(v);    return 1;}void print(int index){    int i;    if(!index)        return;    else    {       print(st[index][3]);       for(int i=0;i<3;i++)        printf("%d ",st[index][i]);       cout<<endl;    }    return;}int main(){    while(cin>>cup[0]>>cup[1]>>cup[2]>>x)    {        int front,rear;        vis.clear();        if(x>cup[0]||x<0) cout<<"ERROR"<<endl;        else        {            st[1][0]=cup[0];            st[1][1]=0;            st[1][2]=0;            st[1][3]=0;            insert(st[1]);            front=1,rear=2;            while(front<rear)            {                int buf[3];                if(st[front][0]==x||st[front][1]==x||st[front][2]==x)                    break;                memcpy(buf,st[front],sizeof(buf));                for(int i=0;i<3;i++)                    for(int j=0;j<3;j++)                {                    if(i!=j)                    {                        if(water(i,j,buf))                        {                            if(insert(buf))                            {                                memcpy(st[rear],buf,sizeof(buf));                                st[rear][3]=front;                                rear++;                            }                            memcpy(buf,st[front],sizeof(buf));                        }                    }                }                front++;            }            if(front<rear)                print(front);            else                printf("没有办法让一个杯子中有%d升水\n",x);        }    }    return 0;}


0 0