当前位置:编程学习 > C/C++ >>

uva10603倒水问题宽度优先遍历!

利用bfs解题,以三个杯子中现有水量作为一个“状态”,从一个状态不断扩展新的状态加入排队数组,这样既可保证找到目标水量时是经过了最少次数的倒水操作。
 
扩展新的状态节点是个稍微难一点的地方,先计算出i给j能倒得水量amount,等于i所剩水与j所差水的最小值。然后当amount!=0时进行倒水操作。vis是判重数组,只需要二维既可,因为三个杯子的水总量是不变的,两个杯子的水量相同时就表明是同一个状态。
 
难度不大,细心既可。
 
转载请注明出处,谢谢
 
http://blog.csdn.net/monkeyduck
 
#include<iostream>  
#include<cstring>  
  
using namespace std;  
  
int vol[3],d,n,front,rear;  
bool flag,vis[201][201];  
struct Node  
{  
    int water[3],s;  
};  
Node result,state[40001];  
void bfs()  
{  
    int i,j;  
    front=rear=0;  
    Node init,tnode;  
    init.water[0]=0;init.water[1]=0;init.water[2]=vol[2];init.s=0;  
    vis[0][0]=1;  
    state[rear++]=init;  
    while(front<rear)  
    {  
        tnode=state[front++];  
        if (tnode.water[0]==d||tnode.water[1]==d||tnode.water[2]==d)  
        {  
            flag=1;  
            result=tnode;  
            break;  
        }  
        for (i=0;i<3;i++)  
        {  
            for (j=0;j<3;j++)  
            {  
                if (i!=j)  
                {  
                    int amount=tnode.water[i]<vol[j]-tnode.water[j]?tnode.water[i]:vol[j]-tnode.water[j];  
                    if (amount!=0)  
                    {  
                        Node nNode;  
                        for (int k=0;k<3;k++)  
                            nNode.water[k]=tnode.water[k];  
                        nNode.water[i]=nNode.water[i]-amount;  
                        nNode.water[j]=nNode.water[j]+amount;  
                        nNode.s=tnode.s+amount;  
                        if (!vis[nNode.water[0]][nNode.water[1]])  
                        {  
                            vis[nNode.water[0]][nNode.water[1]]=1;  
                            state[rear++]=nNode;  
                        }  
                    }  
                }  
            }  
        }  
    }  
}  
int main()  
{  
    cin>>n;  
    while(n--)  
    {  
        cin>>vol[0]>>vol[1]>>vol[2]>>d;  
        flag=0;  
        memset(vis,0,sizeof(vis));  
        bfs();  
        if (flag)  
            cout<<result.s<<" "<<d<<endl;  
        else  
        {  
            for (int i=d-1;i>=0;i--)  
            {  
                for (int j=0;j<=rear;j++)  
                {  
                    Node nn=state[j];  
                    if (nn.water[0]==i||nn.water[1]==i||nn.water[2]==i)  
                    {  
                        cout<<nn.s<<" "<<i<<endl;  
                        flag=1;  
                        break;  
                    }  
                }  
                if (flag) break;  
            }  
        }  
    }  
    return 0;  
}  

 

 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,