• 倒水问题(搜索)


    题意

    有三个杯子,容量分别为\(A,B,C\)

    初始时,\(C\)杯装满了水,而\(A,B\)杯都是空的。

    现在在保证不会有漏水的情况下进行若干次如下操作:

    将一个杯子\(x\)中的水倒到另一个杯子\(y\)中,当\(x\)空了或者\(y\)满了时就停止(满足其中一个条件才停下)。

    请问,在操作全部结束后,\(C\)中的水量有多少种可能性。

    题目链接:https://www.acwing.com/problem/content/3514/

    数据范围

    \(0 \leq A,B,C \leq 4000\)

    思路

    考虑用DFS爆搜,dfs(x, y, z)表示当前搜索到的状态(三个杯子当前的水量)

    下面主要分析时间复杂度。

    每个状态至少会有一个杯子是空的或者满的,因此状态总数为\(O(4001 * 4001 * 2 * 3)\)

    代码

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <set>
    
    using namespace std;
    
    typedef pair<int, int> pii;
    typedef pair<pii, int> ppi;
    
    int v[3];
    set<int> ans;
    set<ppi> st;
    
    void dfs(int x, int y, int z)
    {
        ans.insert(z);
        st.insert({{x, y}, z});
        int t[3] = {x, y, z};
        for(int i = 0; i < 3; i ++) {
            for(int j = 0; j < 3; j ++) {
                if(i == j) continue;
                int tt[3] = {x, y, z};
                int mi = min(tt[i], v[j] - tt[j]);
                tt[i] -= mi, tt[j] += mi;
                if(!st.count({{tt[0], tt[1]}, tt[2]})) dfs(tt[0], tt[1], tt[2]);
            }
        }
    }
    
    int main()
    {
        while(~scanf("%d%d%d", &v[0], &v[1], &v[2])) {
            ans.clear();
            st.clear();
            dfs(0, 0, v[2]);
            printf("%d\n", ans.size());
        }
        return 0;
    }
    
  • 相关阅读:
    面向对象 & sql语句
    MySQL--数据库面试题汇集
    MySQL优化
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    《大道至简》读后感
    JAVA日报
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/16453158.html
Copyright © 2020-2023  润新知