HDU1495 非常可乐

中文题就不翻译了,,

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1495

互相倒水的也是一种典型的搜索题,这里采取的是广搜的方法。

事先可以做一些优化,如果水体积是奇数那么肯定平分不了。取结构体为三个杯子里的水量,这是每执行一步操作后的状态。将初始状态压入队列里,每次计算所有可能的倒水情况,直到出现一种可以平分的状态,或是队列为空。

题目本身很好写,就是每步操作不像迷宫那样可以归到对一个数组的加减,这样代码本身比较冗长,比较考验耐心。

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct node {
    int s1,n1,m1;
    int step;
    friend bool operator < (node a,node b) {//定义结构体与结构体比较大小的方法
        return b.step<a.step;
    }
};
int vis[104][104][104];
int main()
{
    int n,m,s;
    while(cin>>s>>n>>m)
    {
        priority_queue<node> q;//没卵用,直接用queue就好了
        memset(vis,0,sizeof(vis));
        if(s==0&&n==0&&m==0)
            break;
        if(n<m) swap(n,m);
        if(s%2)
        {
            cout<<"NO"<<endl;
            continue;
        }
        node buf,next;
        buf.s1=s;buf.n1=0;buf.m1=0;
        buf.step=0;
        q.push(buf);
        bool flag=false;
        while(!q.empty())
        {
            buf=q.top();
            q.pop();
            if(buf.s1==s/2&&buf.n1==s/2)
            {
                cout<<buf.step<<endl;
                flag=true;
                break;
            }
            int num=min(buf.s1,n-buf.n1);//计算一步操作完成后3个杯子的水量
            int n2=buf.n1+num,s2=buf.s1-num,m2=buf.m1;
            if(!vis[s2][n2][m2])//6种操作,每种差不多,但是都需要自己重写
            {
                vis[s2][n2][m2]=1;
                next.n1=n2;next.m1=m2;next.s1=s2;
                next.step=buf.step+1;
                q.push(next);
            }
            num=min(buf.s1,m-buf.m1);
            m2=buf.m1+num,s2=buf.s1-num,n2=buf.n1;
            if(!vis[s2][n2][m2])
            {
                vis[s2][n2][m2]=1;
                next.n1=n2;next.m1=m2;next.s1=s2;
                next.step=buf.step+1;
                q.push(next);
            }
            num=min(buf.n1,m-buf.m1);
            m2=buf.m1+num,s2=buf.s1,n2=buf.n1-num;
            if(!vis[s2][n2][m2])
            {
                vis[s2][n2][m2]=1;
                next.n1=n2;next.m1=m2;next.s1=s2;
                next.step=buf.step+1;
                q.push(next);
            }
            num=min(buf.n1,s-buf.s1);
            m2=buf.m1,s2=buf.s1+num,n2=buf.n1-num;
            if(!vis[s2][n2][m2])
            {
                vis[s2][n2][m2]=1;
                next.n1=n2;next.m1=m2;next.s1=s2;
                next.step=buf.step+1;
                q.push(next);
            }
            num=min(buf.m1,s-buf.s1);
            m2=buf.m1-num,s2=buf.s1+num,n2=buf.n1;
            if(!vis[s2][n2][m2])
            {
                vis[s2][n2][m2]=1;
                next.n1=n2;next.m1=m2;next.s1=s2;
                next.step=buf.step+1;
                q.push(next);
            }
            num=min(buf.m1,n-buf.n1);
            m2=buf.m1-num,s2=buf.s1,n2=buf.n1+num;
            if(!vis[s2][n2][m2])
            {
                vis[s2][n2][m2]=1;
                next.n1=n2;next.m1=m2;next.s1=s2;
                next.step=buf.step+1;
                q.push(next);
            }
        }
        if(flag==false)
            cout<<"NO"<<endl;
    }
}

你可能感兴趣的:(HDU1495 非常可乐)