博客
关于我
POJ 3414 Pots
阅读量:772 次
发布时间:2019-03-23

本文共 3941 字,大约阅读时间需要 13 分钟。

为了解决这个问题,我们需要找到一种最短的操作序列,使得其中一个容器中恰好有C升的水。我们可以通过广度优先搜索(BFS)来探索所有可能的状态转换,并找到最短路径。

方法思路

  • 状态表示:使用两个变量表示两个容器的当前水量,记录每个状态是否已经被访问过。
  • 操作转换:定义每个操作(FILL, DROP, POUR)对应的状态转换。例如,FILL(1)会将第一个容器的水量填满。
  • 广度优先搜索(BFS):从初始状态(0,0)出发,逐层扩展,处理每个可能的状态,生成新的状态直到达到目标状态或排除不可能的情况。
  • 路径记录:记录每一步的操作,避免重复访问状态,确保找到最短路径。
  • 解决代码

    #include 
    #include
    #include
    #include
    using namespace std;int main() { int a, b, c; scanf("%d%d%d", &a, &b, &c); int MAXN = 100; bool visited[MAXN][MAXN]; queue
    q; struct node { int curr_a, curr_b; int steps; string path; node(int a, int b, int steps, string path) : curr_a(a), curr_b(b), steps(steps), path(path) {} }; node start_node(0, 0, 0, ""); visited[start_node.curr_a][start_node.curr_b] = true; q.push(start_node); string ops[] = {"", "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"}; while (!q.empty()) { auto current = q.front(); q.pop(); if (current.curr_a == c || current.curr_b == c) { cout << current.steps << endl; for (int i = 0; i < current.path.size(); ++i) { cout << ops[current.path[i] - '0'] << endl; } return true; } // Generate all possible moves if (current.path.length() >= 7) continue; // 避免无限循环 // FILL(1) if (current.curr_a < a && !visited[current.curr_a + a][current.curr_b]) { node next = node(current.curr_a + a, current.curr_b, current.steps + 1, current.path + "1"); if (next.curr_a <= MAXN && next.curr_b <= MAXN) { if (!visited[next.curr_a][next.curr_b]) { visited[next.curr_a][next.curr_b] = true; q.push(next); } } } // FILL(2) if (current.curr_b < b && !visited[current.curr_a][current.curr_b + b]) { node next = node(current.curr_a, current.curr_b + b, current.steps + 1, current.path + "2"); if (!visited[next.curr_a][next.curr_b]) { visited[next.curr_a][next.curr_b] = true; q.push(next); } } // DROP(1) if (current.curr_a > 0 && !visited[0][current.curr_b]) { node next = node(0, current(curr_b_b), current.steps + 1, current.path + "3"); if (!visited[next.curr_a][next.curr_b]) { visited[next.curr_a][next.curr_b] = true; q.push(next); } } // DROP(2) if (current.curr_b > 0 && !visited[current.curr_a][0]) { node next = node(current(curr_a, 0, current.steps + 1, current.path + "4"); if (!visited[next.curr_a][next.curr_b]) { visited[next.curr_a][next.curr_b] = true; q.push(next); } } // POUR(1,2) int pour_from = current(curr_a, curr_b); if (pour_from.b < b) { int水量 = min(pour_from.a, b - pour_from.b); if (水量 > 0) { node next = node(current(curr_a - 水量, curr_b + 水量, current.steps + 1, current.path + "5"); if (!visited[next.a][next.b]) { visited[next.a][next.b] = true; q.push(next); } } } // POUR(2,1) if (pour_from.a < a) { int水量 = min(pour_from.b, a - pour_from.a); if (水量 > 0) { node next = node(current(a + 水量, b - 水量), steps + 1, path + "6"); if (!visited[next.a][next.b]) { visited[next.a][next.b] = true; q.push(next); } } } } cout << "impossible" << endl; return false;}

    代码解释

  • 输入处理:读取A, B, C的值。
  • 初始化:创建一个二维数组visited来记录状态是否已经被访问过。使用队列进行BFS,存储当前状态、步骤数和路径。
  • 状态转换:处理每个状态,生成新状态的所有可能,检查是否已经访问过,避免重复。
  • 路径记录:每次生成新状态时,更新操作序列,直到找到目标状态或排除不可能的情况。
  • 通过这种方法,我们可以找到最短的操作序列,或者判断目标状态不可达。

    转载地址:http://xlhzk.baihongyu.com/

    你可能感兴趣的文章
    net网络查看其参数state_dict,data,named_parameters
    查看>>
    Net连接mysql的公共Helper类MySqlHelper.cs带MySql.Data.dll下载
    查看>>
    NeurIPS(神经信息处理系统大会)-ChatGPT4o作答
    查看>>
    neuroph轻量级神经网络框架
    查看>>
    Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population(7)
    查看>>
    new Blob()实现不同类型的文件下载功能
    查看>>
    New Concept English three (35)
    查看>>
    NEW DATE()之参数传递
    查看>>
    New Journey--工作五年所思所感小记
    查看>>
    new Queue(REGISTER_DELAY_QUEUE, true, false, false, params)
    查看>>
    New Relic——手机应用app开发达人的福利立即就到啦!
    查看>>
    new work
    查看>>
    new 一个button 然后dispose,最后这个button是null吗???
    查看>>
    NewspaceGPT的故事续写能力太强了
    查看>>
    NewspaceGPT绘制时序图
    查看>>
    NewspaceGPT绘制类图
    查看>>
    new一个对象的过程
    查看>>
    new和delete用法小结
    查看>>
    new对象时,JVM内部究竟藏了什么小秘密?
    查看>>
    new操作符的实现原理
    查看>>