NYOJ—三个水杯【搜索|广搜|BFS】

来源:互联网 发布:手机淘宝标题优化技巧 编辑:程序博客网 时间:2024/04/29 22:33

三个水杯

时间限制:1000 ms | 内存限制:65535 KB
难度:4

描述

给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

输入

第一行一个整数N(0

输出

每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1

样例输入

2
6 3 1
4 1 1
9 3 2
7 1 1

样例输出

3
-1

思路

既然是找最少的次数,那就使用广搜,把当前状态每一个可以互相倒水且不与之前重复的状态放入队列中,每次取对首元素时判断是否为最终状态,不是的话继续放。如果取到队空则说明达不到目标返回-1

代码如下

#include <iostream>#include <stdio.h>#include <map>#include <queue>using namespace std;int m[3];int z_m[3];struct zhuang_tai{    int L[3];    int sum;    bool operator < (const zhuang_tai &a)const      ///重载<运算符用于结构体排序    {            if(a.L[0]==L[0])                if(a.L[1]==L[1])                    if(a.L[2]==L[2]);                    else                        return a.L[2]<L[2];                else                    return a.L[1]<L[1];            return a.L[0]<L[0];    }}ans,k;queue<zhuang_tai>q;map<zhuang_tai,int>mp;int pan(zhuang_tai a)        ///判断是否与目标状态相同{    if(a.L[0]==z_m[0]&&a.L[2]==z_m[2]&&a.L[1]==z_m[1])        return 1;    return 0;}void swp(int a ,int b,int c){    zhuang_tai ans1;    if(ans.L[a]<(m[b]-ans.L[b]))///如果第一个杯子水小于要倒的杯子剩余容量就全部倒到第二个杯子    {        ans1.L[a]=0;        ans1.L[b]=ans.L[b]+ans.L[a];    }    else                        ///否则把第二个杯子倒满    {        ans1.L[a]=ans.L[a]-(m[b]-ans.L[b]);        ans1.L[b]=m[b];    }    ans1.L[c]=ans.L[c];    ans1.sum=0;    if(!mp.count(ans1))         ///判断三种杯子状态是否出现过,如果没有出现过就入队    {        mp[ans1]++;        ans1.sum=ans.sum+1;        q.push(ans1);    }}int main(){    int w;cin>>w;    while(w--)    {        while(!q.empty())            q.pop();        mp.clear();        cin>>m[0]>>m[1]>>m[2];        cin>>z_m[0]>>z_m[1]>>z_m[2];        ans.L[0]=m[0];        ans.L[1]=0;        ans.L[2]=0;        ans.sum=0;        q.push(ans);        int summ=0;        while(!q.empty())        {            ans=q.front();            summ++;            q.pop();            if(pan(ans))  ///判断是否与目标状态相同            {                cout<<ans.sum<<endl;                 goto go;      ///跳过输出-1的情况            }            swp(0,1,2);    ///六种相互倒的状态            swp(0,2,1);            swp(1,0,2);            swp(1,2,0);            swp(2,1,0);            swp(2,0,1);        }        cout<<-1<<endl;        go:;    }    return 0;}
0 0