首页 > 其他分享 >HDU 1495 非常可乐

HDU 1495 非常可乐

时间:2022-12-23 18:01:37浏览次数:76  
标签:HDU 毫升 int st 1495 杯子 平分 可乐

HDU 1495 非常可乐

​ 有一壶 S 毫升的酒,酒壶容量也是 S 毫升(没有刻度),现在有两个 N 毫升和 M 毫升的酒杯(也都没有刻度),\(S=N+M\),\(0 \le S,N,M \le 101\),这三只容器均可以相互倒酒,请问通过这三只容器之间相互倒酒,能否平分这 S 毫升的酒至两个酒杯之中?若能够平分的话,输出一行为最小的倒酒次数;若无法平分,输出一行NO。

思路:

​ 数据比较小,先往暴力的方向想。因为有小次数,也就是等效于最短路问题,可以想到是搜索。

​ 搜索的过程中有一个比较重要的就是转移。这一题的状态设计是需要做一些思考的。我们直接用3个容器当前的可乐的量来做状态,每次转移都是某个杯子往某个杯子里倒水。因为酒杯和酒壶都没有刻度,所以每次倒的时候会发生两种情况中至少一种:倒入的杯子满了或是倒出的杯子空了。根据这个,就可以模拟出倒水的过程了。

​ 因为BFS是基于队列来拓展的一个过程,所以第一次出现在队列中一定是最小的倒酒次数。

代码:

​ 记得判重。不要把起点漏掉了。

#include <bits/stdc++.h>

using namespace std;

int a, b, c;
int w[3];
int st[110][110][110]; //判重

struct node 
{
    int v[3];//三个杯子当前的状态
    int step;
};

void bfs()
{
    memset(st, 0, sizeof st);
    queue<node> q;
    q.push({w[0], 0, 0, 0}); //初始状态
    st[w[0]][0][0] = 1;

    while(q.size())
    {
        node t = q.front();
        q.pop();

        if(t.v[0] == t.v[2] && t.v[1] == 0) //平分时
        {
            cout << t.step << '\n';
            return;
        }

        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                if(i != j)
                {
                    node temp = t;
                    int minn = min(temp.v[i], w[j] - temp.v[j]); //从i倒水到j
                    // 倒入的杯子满了或是倒出的杯子空了
                    temp.v[i] -= minn, temp.v[j] += minn;

                    if(!st[temp.v[0]][temp.v[1]][temp.v[2]])
                    {
                        temp.step ++;
                        q.push(temp);
                        st[temp.v[0]][temp.v[1]][temp.v[2]] = 1;
                    }
                }
            }
        }
    }
    cout << "NO" << '\n';
}

int main()
{
    while(cin >> w[0] >> w[1] >> w[2])
    {
        if(w[0] == 0 && w[1] == 0 && w[2] == 0)  
            break;
        if(w[1] > w[2])  //默认杯2的容量大于等于杯1,降低编码难度
            swap(w[1], w[2]);
        if(w[0] % 2 == 1) //可行性剪枝,易知若可乐总数是奇数,无法平分  
            cout << "NO" << '\n';
        else 
            bfs();
    }
}

标签:HDU,毫升,int,st,1495,杯子,平分,可乐
From: https://www.cnblogs.com/DM11/p/17001261.html

相关文章

  • hdu: 阿牛的EOF牛肉串(二维递推)
    ProblemDescription今年的ACM暑期集训队一共有18人,分为6支队伍。其中有一个叫做EOF的队伍,由04级的阿牛、XC以及05级的COY组成。在共同的集训生活中,大家建立了深厚的友谊......
  • hdu:折线分割平面(递推)
    ProblemDescription我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线......
  • HDU-2639 Bone Collector ||
    HDU-2639BoneCollector||01背包问题,但是需要输出的是可以获得的第\(k\)大价值。思路:状态定义?我们要求的是第\(k\)大价值,所以当我们得到一个当前第\(k+1\)......
  • HDU4553 线段树维护最长连续区间
    //题意:(略了)//思路:这里很明显是要维护区间最大连续子段,按照以下优先级查找//A1.左边区间的连续子段是否满足//A2.左右两个区间中间合并起来的子段是否满足......
  • HDU 2602 Bone collector
    HDU2602Bonecollector题意:已知\(N\)个糖果的重量和价值.我们有一个口袋,最多可以装\(V\)重量的糖果.问口袋最多能放多少价值的糖果进去?思路:01背包问题......
  • HDU-Red and Black
     ProblemDescriptionThereisarectangularroom,coveredwithsquaretiles.Eachtileiscoloredeitherredorblack.Amanisstandingonablacktile.Froma......
  • HDU5091 Beam Cannon
    \(HDU5091\)\(Beam\)\(Cannon\)一、题目大意有\(n\)个点(\(n<=10000\)),点的坐标绝对值不超过\(20000\),然后问你用一个\(w*h(1<=w,h<=40000)\)的矩形,矩形的边平行于坐标......
  • I Hate It HDU - 1754 - 线段树
    很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。这让很多学生很反感。不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,......
  • HDU 4614 ——线段树+二分
    //题意:茜茜学姐的情人节到了!众所周知,茜茜学姐喜欢帅气的学弟,所以她当然有很多学弟送的花瓶,据不完全统计,茜茜学姐有N个花瓶(标号为0~N-1)。当然茜茜学姐也是个魅力四射......
  • hdu:继续畅通工程(kruskal的MST并查集实现)
    ProblemDescription省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表......