图论08-图的建模-状态的表达与理解 - 倒水问题为例

文章目录

  • 状态的表达
    • 例题1
    • 题解
      • 1 终止条件:有一个数位为4
      • 2 状态的改变:a表示十位数,b表示个位数
      • 3 其他设置
    • 例题2 力扣773 滑动谜题
      • Java
      • C++

状态的表达

例题1

在这里插入图片描述

从初始的(x,y)状态,到最后变成(4,?)或者(?,4).

本道题对于(x,y)的状态,可以使用10x+y进行表达,也就是变成了一个数字,分别放在不同的数位上。
但是本状态的表示方法不适用单个数组超过9的,因为一个数位只能表示0-9.。

涉及思想:状态压缩

题解

1 终止条件:有一个数位为4

if(next / 10 == 4 || next % 10 == 4) {end = next;return;
}

2 状态的改变:a表示十位数,b表示个位数

重复添加满水不影响结果

a = cur / 10, b = cur % 10;

要达到(4,?)或者(?,4)的办法

  • a桶灌满5升水
  • b桶灌满3升水
  • a桶的水倒掉
  • b桶的水倒掉
  • a桶中的水倒进b桶中 --> 最多能倒a升,还能倒b桶剩余空闲容量=(3-b桶当前容量)
  • b桶中的水倒进a桶中
nexts.add(5 * 10 + b);
nexts.add(a * 10 + 3);
nexts.add(a * 10 + 0);
nexts.add(0 * 10 + b);int x = Math.min(a, 3 - b);
nexts.add((a - x) * 10 + (b + x));int y = Math.min(b, 5 - a);
nexts.add((a + y) * 10 + (b - y));

3 其他设置

  • 访问数组用于记录访问过的状态
 boolean[] visited = new boolean[100];
  • 队列用于记录访问的每个节点的状态
Queue<Integer> queue = new LinkedList<>();
  • 记录上一个状态
pre = new int[100];
  • 记录状态变化
    • 首先要把pre数组填好,根据pre数组将遍历的过程从最终结果向前找初始状态。最终再翻转链表。
    • 做标记 设置end = -1
      如果end倒最后还是-1,说明问题没有解。
import java.util.*;
import java.util.ArrayList;public class WaterPuzzle {private int[] pre;private int end = -1;public WaterPuzzle(){Queue<Integer> queue = new LinkedList<>();boolean[] visited = new boolean[100];pre = new int[100];queue.add(0);visited[0] = true;while (!queue.isEmpty()){int cur = queue.remove();int a = cur / 10, b = cur % 10;// max a = 5, max b = 3ArrayList<Integer> nexts = new ArrayList<>();nexts.add(5 * 10 + b);nexts.add(a * 10 + 3);nexts.add(a * 10 + 0);nexts.add(0 * 10 + b);int x = Math.min(a, 3 - b);nexts.add((a - x) * 10 + (b + x));int y = Math.min(b, 5 - a);nexts.add((a + y) * 10 + (b - y));for(int next: nexts)if(!visited[next]){queue.add(next);visited[next] = true;pre[next] = cur;if(next / 10 == 4 || next % 10 == 4) {end = next;return;}}}}public Iterable<Integer> result(){ArrayList<Integer> res = new ArrayList<>();if(end == -1) return res;int cur = end;while(cur != 0){res.add(cur);cur = pre[cur];}res.add(0);Collections.reverse(res);return res;}public static void main(String[] args){System.out.println((new WaterPuzzle()).result());}
}

例题2 力扣773 滑动谜题

Java

/// Leetcode 773import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
import java.util.HashMap;public class Solution {private int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};public int slidingPuzzle(int[][] board) {Queue<String> queue = new LinkedList<>();HashMap<String, Integer> visited = new HashMap<>();String initalState = boardToString(board);if(initalState.equals("123450")) return 0;queue.add(initalState);visited.put(initalState, 0);while(!queue.isEmpty()){String cur = queue.remove();ArrayList<String> nexts = getNexts(cur);for(String next: nexts)if(!visited.containsKey(next)){queue.add(next);visited.put(next, visited.get(cur) + 1);if(next.equals("123450"))return visited.get(next);}}return -1;}private ArrayList<String> getNexts(String s){int[][] cur = stringToBoard(s);int zero;for(zero = 0; zero < 6; zero ++)if(cur[zero / 3][zero % 3] == 0)break;ArrayList<String> res = new ArrayList<>();int zx = zero / 3, zy = zero % 3;for(int d = 0; d < 4; d ++){int nextx = zx + dirs[d][0], nexty = zy + dirs[d][1];if(inArea(nextx, nexty)){swap(cur, zx, zy, nextx, nexty);res.add(boardToString(cur));swap(cur, zx, zy, nextx, nexty);}}return res;}private boolean inArea(int x, int y){return x >= 0 && x < 2 && y >= 0 && y < 3;}private void swap(int[][] board, int x1, int y1, int x2, int y2){int t = board[x1][y1];board[x1][y1] = board[x2][y2];board[x2][y2] = t;}private String boardToString(int[][] board){StringBuilder sb = new StringBuilder();for(int i = 0; i < 2; i ++)for(int j = 0; j < 3; j ++)sb.append(board[i][j]);return sb.toString();}private int[][] stringToBoard(String s){int[][] board = new int[2][3];for(int i = 0; i < 6; i ++)board[i / 3][i % 3] = s.charAt(i) - '0';return board;}public static void main(String[] args){int[][] board = {{1, 2, 3}, {4, 0, 5}};System.out.println((new Solution()).slidingPuzzle(board));}
}

C++

class Solution {
public:int slidingPuzzle(vector<vector<int>>& board) {
//记录最终状态const string sol = "123450";const int m = 2, n = 3;const int dirs[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};//记录初始状态,使用字符串记录string init;for (auto &line: board) {for (auto &grid: line) {init.push_back('0' + grid);}}//构造队列,并初始化queue<string> q{{init}};//设置unordered_set,记录访问状态unordered_set<string> vis{{init}};//记录步数int ans = 0;//开始BFSwhile (!q.empty()) {int size = q.size();for (int i = 0; i < size; ++i) {auto &p = q.front();//出口if (p == sol) {return ans;}//先找0号的位置int idx0 = p.find('0');//四联通拓展for (int a = 0; a < 4; ++a) {//求0号元素的二维新坐标int nx = idx0 / n + dirs[a][0], ny = idx0 % n + dirs[a][1];//求0号元素映射到一维数组中的坐标int idx1 = nx * n + ny;//判断边界if (nx >= 0 && nx < m && ny >= 0 && ny < n) {//交换两个元素的位置swap(p[idx0], p[idx1]);//如果当前状态没有测试过if (!vis.count(p)) {//加入访问数组vis.insert(p);//入队q.push(p);}//恢复原来的状态,继续交换位置然后将状态入队列swap(p[idx0], p[idx1]);}}q.pop();}//对头出队的时候,开始移动到下一个状态,因此步数+1++ans;}return -1;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/158607.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

乌班图 Linux 系统 Ubuntu 23.10.1 发布更新镜像

Ubuntu 团队在其官网上发布了Ubuntu 23.10.1 版本,这是目前较新的 Ubuntu 23.10(Focal Fossa)操作系统系列的第一个发行版,旨在为社区提供最新的安装媒体。Ubuntu 22.04 LTS(Focal Fossa)操作系统系列于 2022 年 4 月 21 日发布。 Ubuntu 23.10 LTS(长期支持版本)可用…

Android Studio中配置Git

安装Git 在安装Android Studio之前&#xff0c;需要先安装Git。可以从Git官网下载并安装Git&#xff1a;https://git-scm.com/downloads 在Android Studio中配置Git 在Android Studio中&#xff0c;依次点击“File” -> “Settings”&#xff0c;在弹出的窗口中选择“Ver…

el-table表格设置——动态修改表头

(1) 首先是form表单写表单设置按钮&#xff1a; &#xff08;1.1&#xff09;使用el-popover&#xff0c;你需要修改的是this.colOptions&#xff0c;colSelect: <el-popover id"popover" popper-class"planProver" placement"bottom" width&…

推荐彩虹知识商城源码

彩虹知识商城7.0.3小森升级版新增供货商开心学习版&#xff0c;新增邮件提醒功能&#xff0c;支持给用户发订单、结算等邮件通知&#xff0c;支持给管理员发送提现、域名审核等邮件通知&#xff0c;支持设置手续费最低扣除金额&#xff0c;修复了其他一些已知问题。 演示地址&…

基于深度学习的目标检测算法 计算机竞赛

文章目录 1 简介2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 1 简介 &#x1f5…

HTML脚本、字符实体、URL

HTML脚本&#xff1a; JavaScript 使 HTML 页面具有更强的动态和交互性。 <script> 标签用于定义客户端脚本&#xff0c;比如 JavaScript。<script> 元素既可包含脚本语句&#xff0c;也可通过 src 属性指向外部脚本文件。 JavaScript 最常用于图片操作、表单验…

Python+Selenium自动化测试框架详解

什么是Selenium&#xff1f; Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分&#xff1a;Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE&#xff1a;Firefox的…

智能政务,办事更轻松!拓世法宝AI智慧政务数字人一体机,重新定义你的政务办理体验!

在构建现代化的政务服务体系中&#xff0c;高效、便捷是最重要的衡量标准。随着信息化技术的发展&#xff0c;很多政务服务已经实现了重要的线上办理&#xff0c;减轻了公民和企业的办事负担&#xff0c;同时也提升了政府部门的服务效率。可是&#xff0c;一些场景下的办事流程…

安全第一!速卖通测评补单稳定的系统注意事项大盘点

对新卖家而言&#xff0c;测评并非可耻之事&#xff0c;反而是无法起步、耗费自身时间才是真正的可耻。由于速卖通新店几乎无法获得任何活动的支持&#xff0c;流量也基本没有&#xff0c;因此要在90天内达成60单的业绩对于许多卖家来说都是一项挑战。因此&#xff0c;通过快速…

天津优选Java培训机构 影响Java培训费用的因素

Java作为如今流行的计算机编程语言&#xff0c;其优势在于言语简略、面向对象&#xff0c;并且应用广泛。随着市场对于Java开发人员的需求越来越大&#xff0c;越来越多非本专业的人也通过培训转行进入IT行业。 Java的就业优势 市场需求大&#xff1a;Java人才的市场需求很大…

制造业经营效益差?业务数据管理是关键

《中国制造2025》 指出&#xff0c;目前中国制造业整体尚处于由工业2.0向工业3.0过渡的阶段&#xff0c;而欧美的制造强国已提出工业4.0概念&#xff0c;由“制造”迈向“智造”&#xff0c; 实现智能工厂、 智能生产和智能物流&#xff0c;建立一个高度灵活的个性化和数字化的…

基于FPGA的图像差分运算及目标提取实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2022/07/28 01:51:…