博客
关于我
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/

    你可能感兴趣的文章
    Mysql中索引的分类、增删改查与存储引擎对应关系
    查看>>
    Mysql中索引的最左前缀原则图文剖析(全)
    查看>>
    MySql中给视图添加注释怎么添加_默认不支持_可以这样取巧---MySql工作笔记002
    查看>>
    Mysql中获取所有表名以及表名带时间字符串使用BetweenAnd筛选区间范围
    查看>>
    Mysql中视图的使用以及常见运算符的使用示例和优先级
    查看>>
    Mysql中触发器的使用示例
    查看>>
    Mysql中设置只允许指定ip能连接访问(可视化工具的方式)
    查看>>
    mysql中还有窗口函数?这是什么东西?
    查看>>
    mysql中间件
    查看>>
    MYSQL中频繁的乱码问题终极解决
    查看>>
    MySQL为Null会导致5个问题,个个致命!
    查看>>
    MySQL为什么不建议使用delete删除数据?
    查看>>
    MySQL主从、环境搭建、主从配制
    查看>>
    Mysql主从不同步
    查看>>
    mysql主从同步及清除信息
    查看>>
    MySQL主从同步相关-主从多久的延迟?
    查看>>
    mysql主从同步配置方法和原理
    查看>>
    mysql主从复制 master和slave配置的参数大全
    查看>>
    MySQL主从复制几个重要的启动选项
    查看>>
    MySQL主从复制及排错
    查看>>