HDU1495 非常可乐 题解

原题链接

Description

原题的表述写得很迷,遂重述:

给定三个容器 \(\text{s},\text{n},\text{m}\),体积分别为 \(S,N,M\),满足 \(S=N+M\)。你可以将其中一个容器中的可乐倒进另一个容器中,但是要么把该容器中的可乐倒空,要么让另一个容器中装满可乐。初始状态 \(\text{s}\) 中装满可乐,而 \(\text{n}\) 和 \(\text{m}\) 为空。现欲使一个容器为空,且另外两个容器中可乐均分。试问能否到达此状态,如果能,求最少的倒可乐次数。

Solution

如果 \(S\) 是奇数,那么可乐不能均分。接下来假设 \(S\) 为偶数,令 \(\dfrac{S}{2}=:T\)。

如果 \(T\) 不能被 \(N\) 和 \(M\) 线性表示(即不存在整数 \(x\) 和 \(y\) 使得 \(Nx+My=T\)),那么可乐不能被均分。这是因为在任一时刻,三个容器中的可乐体积都可被 \(N\) 和 \(M\) 线性表示(由归纳可证明)。接下来假设 \(T\) 可被 \(N\) 和 \(M\) 线性表示,由裴蜀定理知该条件等价于 \(T\) 是 \(\gcd(N,M)\) 的倍数。

如果 \(N=M\),那么只需操作 \(1\) 次,即将可乐从 \(\text{s}\) 倒入 \(\text{n}\) 或 \(\text{m}\)。接下来假设 \(N>M\),显然总操作数至少为 \(2\)。

由于 \(M<T\),最终盛有可乐的容器只能是 \(\text{s}\) 和 \(\text{n}\)。

因为 \(S=N+M\),所以只要是从 \(\text{s}\) 中倒出可乐,被倒入可乐的容器必满,于是我们可视 \(\text{s}\) 为一无限可乐源。

\(\text{n}\) 的可乐体积 \(\nu\) 与 \(\text{m}\) 的可乐体积 \(\mu\) 构成的有序对 \((\nu,\mu)\) 是一状态。我们的问题可以转化为:只通过下面给定的 \(6\) 种合法操作,将 \((\nu, \mu)\) 从 \((0,0)\) 转移至 \((T,0)\),求出最短转移路径。

  1. 从 \(\text{s}\) 中取可乐,装满 \(\text{n}\)
  2. 向 \(\text{s}\) 中倒可乐,倒空 \(\text{n}\)
  3. 从 \(\text{s}\) 中取可乐,装满 \(\text{m}\)
  4. 向 \(\text{s}\) 中倒可乐,倒空 \(\text{m}\)
  5. 将 \(\text{n}\) 的可乐倒入 \(\text{m}\)
  6. 将 \(\text{m}\) 的可乐倒入 \(\text{n}\)

接下来,我们谈到装满某一容器时,特指从 \(\text{s}\) 中取可乐装满该容器;同理,当谈到倒空某一容器时,特指将该容器中的可乐全部倒入 \(\text{s}\) 中。无论操作结果如何,\(\text{s}\) 和 \(\text{m}\) 的互倒总不称为倒满或倒空。这样规定的原因是:\(\text{s}\) 和 \(\text{m}\) 的互倒结果往往是难以预测的,比如将 \(\text{n}\) 的可乐倒入 \(\text{m}\),结果既可能是把 \(\text{n}\) 倒空,也可能是把 \(\text{m}\) 装满。而涉及 \(\text{s}\) 的操作结果往往是确定的,比如将 \(\text{s}\) 中的可乐倒入 \(\text{n}\),结果一定是装满了 \(\text{n}\)(或许 \(\text{s}\) 被倒空了,但这不重要,因为我们考察的状态中只涉及 \(\text{n}\) 和 \(\text{m}\) 的可乐体积)。我们可以不把 \(\text{s}\) 看作容器,而是视为一片无尽的可乐海洋,你可以尽情往其中倒可乐,也可以尽情从中舀取可乐。之后提到的容器,都是仅指 \(\text{n}\) 和 \(\text{m}\)。

接下来考虑三个特殊状态:

  • \((N,0)\):该状态只可能在第一步转移到达。如果在后续转移过程中出现该状态,那么该转移路径一定不是最短的。
  • \((0,M)\):与 \((N,0)\) 同理,该状态只可能在第一步转移到达。
  • \((N,M)\):该状态一定不会出现在最短转移路径中,因为它只能向上述两个状态转移。

考虑最短转移路径需满足的性质:

  • 不可能连续执行两次相同操作。
  • 装满某个容器 \(a\) 后,不可能再将可乐从另一容器 \(b\) 中倒入 \(a\),因为 \(a\) 已经满了。
  • 装满某个容器 \(a\) 后,下一步不可能倒空 \(a\),否则不如直接倒空 \(a\)。
  • 倒空某个容器 \(a\) 后,不可能再将可乐从 \(a\) 中倒入另一容器 \(b\),因为 \(a\) 已经空了。
  • 倒空某个容器 \(a\) 后,下一步不可能装满 \(a\),否则不如直接装满 \(a\)。
  • 如果当前容器 \(a\) 是空的或满的,且下一步操作不是首步操作,那么下一步不可能是倒空或装满另一容器 \(b\),否则会到达上述三个特殊状态中的某一个。
  • 将可乐从某容器 \(a\) 倒入另一容器 \(b\) 后,不可能再将可乐从 \(b\) 倒入 \(a\)。因为任一时刻 \(\text{n}\) 和 \(\text{m}\) 中必有一个是满或空的,来回倒两次状态不改变。

结合上述性质,可以得到如下结论:

  • 装满某容器 \(a\) 后,下一步只能是将 \(a\) 的可乐倒入另一容器 \(b\)。
  • 倒空某容器 \(a\) 后,下一步只能是将另一容器 \(b\) 的可乐倒入 \(a\)。
  • 将可乐从 \(a\) 倒入 \(b\) 后,有且仅有两种情况:\(a\) 是空的、\(b\) 是满的——两者不可能同时发生,否则在最短转移路径中会出现特殊状态。
    • 如果 \(a\) 是空的,那么下一步只能是装满 \(a\)。
    • 如果 \(b\) 是满的,那么下一步只能是倒空 \(b\)。

因此,最短转移路径只在下面两种策略中取到:

策略(一):先装满 \(\text{n}\)

策略(二):先装满 \(\text{m}\)

接下来我们求两种策略的总操作数 \(\text{step}_1\) 和 \(\text{step}_2\)。

分析策略(一)

设整个流程装满 \(\text{n}\) 的总次数为 \(x^*\),倒空 \(\text{m}\) 的总次数为 \(y^*\)。显然 \(x^*,y^*\) 均为正整数,有 \(Nx^*-My^*=T\) 成立。

设丢番图方程 \(Nx-My=T\) 的通解形式为

\[(x,y)=(kM+x_0,kN+y_0) \]

其中 \(k\) 是整数,\((x_0,y_0)\) 是方程的一组特解。

我们可以证明,丢番图方程的所有解中,使 \(y\) 取最小正整数的解正是 \((x^*,y^*)\)。

设使 \(y\) 取最小正整数的解为 \((x',y')\),因为 \((x^*,y^*)\) 是丢番图方程的正整数解,所以 \(y^* \ge y'\)。假设某一时刻刚将 \(\text{m}\) 倒空,此时装满 \(\text{n}\) 的次数是 \(\zeta\),倒空 \(\text{m}\) 的次数为 \(y'\),则 \(\text{n}\) 中的可乐体积 \(\nu = N\zeta -My'\)。已知 \(T=Nx'-My'\),而 \(0<\nu<N\),于是 \(\zeta = x'\),进而 \(\nu = T\)。又已将 \(\text{m}\) 倒空,故\((\nu,\mu)=(T,0)\),流程结束。这说明整个流程倒空 \(\text{m}\) 的总次数为 \(y'\),即 \((x',y')=(x^*,y^*)\)。

由流程图可得 \(\text{step}_1 = 2(x^*+y^*)-1\)。接下来我们求 \((x^*,y^*)\)。

令 \(d:=\gcd(N,M)\)。又令 \(n:=\dfrac{N}{d}\),\(m:=\dfrac{M}{d}\),\(t:=\dfrac{T}{d}\),显然 \(n\) 与 \(m\) 互素且均为 \(>1\) 的奇数。

原方程可化为 \(nx-my=t\),通解形式变为 \((x,y)=(km+x_1,kn+x_1)\)。

注意到方程存在一组特解 \((x_1,y_1)=\left(\dfrac{m+1}{2},\dfrac{n-1}{2}\right)\),于是通解可写为

\[(x,y) = \left(km+\frac{m+1}{2},kn+\frac{n-1}{2}\right) \]

令 \(kn + \dfrac{n-1}{2} > 0\),得 \(k_{\min} = 0\)。于是 \((x^*,y^*) = \left(\dfrac{m+1}{2},\dfrac{n-1}{2}\right)\),进而

\[\text{step}_1 = 2\left(\frac{m+1}{2}+\frac{n-1}{2}\right)-1=m+n-1=\frac{N+M}{\gcd(N,M)}-1 \]

分析策略(二)

设整个流程装满 \(\text{m}\) 的总次数为 \(x^*\),倒空 \(\text{n}\) 的总次数为 \(y^*\)。显然 \(x^*,y^*\) 均为正整数,有丢番图方程 \(Mx^*-Ny^*=T\) 成立。

设丢番图方程 \(Mx-Ny=T\) 的通解形式为

\[(x,y)=(kN+x_0,kM+y_0) \]

其中 \(k\) 是整数,\((x_0,y_0)\) 是方程的一组特解。

我们可以证明,丢番图方程的所有解中,使 \(x\) 取最小正整数的解正是 \((x^*,y^*)\)。

设使 \(x\) 取最小正整数的解为 \((x',y')\),因为 \((x^*,y^*)\) 是丢番图方程的正整数解,所以 \(x^* \ge x'\)。假设某一时刻刚将可乐从 \(\text{m}\) 倒入 \(\text{n}\) 中,此时装满 \(\text{m}\) 的次数为 \(x'\),倒空 \(\text{n}\) 的次数是 \(\zeta\),则 \(\text{n}\) 中的可乐体积 \(\nu = Mx' -N\zeta\)。已知 \(T=Mx'-Ny'\),而 \(0<\nu<N\),于是 \(\zeta = y'\),进而 \(\nu = T\)。\(\text{n}\) 不是满的,故 \(\text{m}\) 是空的,于是 \((\nu,\mu)=(T,0)\),流程结束。这说明整个流程装满 \(\text{m}\) 的总次数为 \(x'\),即 \((x',y')=(x^*,y^*)\)。

由流程图可得 \(\text{step}_2 = 2(x^*+y^*)\)。接下来我们求 \((x^*,y^*)\)。

同(一)理,做相同的代换后,原方程可化为 \(mx-ny=t\),通解形式变为 \((x,y)=(kn+x_1,km+x_1)\)。

注意到方程存在一组特解 \((x_1,y_1)=\left(\dfrac{n+1}{2},\dfrac{m-1}{2}\right)\),于是通解可写为

\[(x,y) = \left(kn+\frac{n+1}{2},km+\frac{m-1}{2}\right) \]

令 \(kn + \dfrac{n+1}{2} > 0\),得 \(k_{\min} = 0\)。于是 \((x^*,y^*) = \left(\dfrac{n+1}{2},\dfrac{m-1}{2}\right)\),进而

\[\text{step}_2 = 2\left(\frac{n+1}{2}+\frac{m-1}{2}\right)=m+n=\frac{N+M}{\gcd(N,M)} \]

结论

由于 \(\text{step}_1 < \text{step}_2\),所以最终答案

\[\text{Ans}=\text{step}_1 = \frac{N+M}{\gcd(N,M)}-1 \]

Code

#include <cstdio>
using namespace std;

int gcd(int x, int y) {
    return y == 0 ? x : gcd(y, x % y);
}

int main() {
    int s, n, m;
    while (scanf("%d%d%d", &s, &n, &m) && s && n && m) {
        int d = gcd(n, m);
        if ((s & 1) || s / 2 % d)
            puts("NO");
        else
            printf("%d\n", s / d - 1);
    }
    return 0;
}
posted @ 2026-07-13 19:14  SHUddol  阅读(22)  评论(0)    收藏  举报