博客
关于我
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一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>
    MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
    查看>>
    MySQL不同字符集及排序规则详解:业务场景下的最佳选
    查看>>
    Mysql不同官方版本对比
    查看>>
    MySQL与Informix数据库中的同义表创建:深入解析与比较
    查看>>
    mysql与mem_细说 MySQL 之 MEM_ROOT
    查看>>
    MySQL与Oracle的数据迁移注意事项,另附转换工具链接
    查看>>
    mysql丢失更新问题
    查看>>
    MySQL两千万数据优化&迁移
    查看>>
    MySql中 delimiter 详解
    查看>>
    MYSQL中 find_in_set() 函数用法详解
    查看>>
    MySQL中auto_increment有什么作用?(IT枫斗者)
    查看>>
    MySQL中B+Tree索引原理
    查看>>
    mysql中cast() 和convert()的用法讲解
    查看>>
    mysql中datetime与timestamp类型有什么区别
    查看>>