10.22A*算法,华容道,状态压缩

A*

P1379华容道

问题是要从初始布局用最少的步骤到目标布局,每次只能动0周围的格子,就是华容道;

怎么用算法的思路解决?

状态压缩思路

每个数字就代表当前的状态,队列和map函数都记录的是当前的状态数,

描述一个状态有矩阵形式也有一个数形式

这里c[3][3]是描述状态的矩阵,n就是描述状态的数

这里是把n转化为矩阵形式,并且得到矩阵中0的位置,用f,g记录

执行交换操作无法在数中执行,比较抽象,所以是要转为矩阵,在矩阵里尝试交换,交换完后再转回数的形式进行存储,就是为了节约空间,ns是当前矩阵按当前遍历次序移动完后的结果,

如果在Map里没有出现,就是Map里没有这个数(这个状态),就意味着是新到的状态,由于是bfs,所以必定是到达这个状态的最小步数 

#include<iostream>
#include<map>
#include<queue>
#include<algorithm>
#define ll long long//在这里看到一种很骚的操作:直接把int定义成long long;main函数用signed类型--麻麻再也不怕我忘开long long了!
using namespace std;
const ll dx[]={-1,0,0,1},dy[]={0,-1,1,0};//转移数组;
ll n;
int  main()
{cin>>n;queue<ll> q;q.push(n);map<ll,ll> m;m[n]=0;while(!q.empty()){int u=q.front(); //初始状态入队列int c[3][3],f=0,g=0,n=u;q.pop();if(u==123804765)break;for(ll i=2;i>=0;i--)for(ll j=2;j>=0;j--){c[i][j]=n%10,n/=10;if(!c[i][j])f=i,g=j;}for(ll i=0;i<4;i++){ll nx=f+dx[i],ny=g+dy[i],ns=0;if(nx<0||ny<0||nx>2||ny>2)continue; //越界就不执行swap(c[nx][ny],c[f][g]);for(ll i=0;i<3;i++)for(ll j=0;j<3;j++)ns=ns*10+c[i][j];//矩阵转数列 if(!m.count(ns)){m[ns]=m[u]+1;//map去重的同时顺便统计到达这个状态所需的步数q.push(ns);}swap(c[nx][ny],c[f][g]);//状态复原}}cout<<m[123804765]<<endl; // map的下标直接用数列表示return 0;
}

map

map查找

 map操作函数

常用的count(),返回的是出现次数,int型,返回的是键的出现次数,不是键对应的值所以只可能是0或者1

如果是!m.count(n)就表示是没有找到时触发,即此时map里还没有n这个键

m.count(n)就表示找到了这个元素,即map里此时已经有了n这个元素

 

A*方法

 

这一步是在判断当前状态是否还有可能是解,step是当前步数,cnt是估价函数值,cnt的值的确定,是有双重循环,一检测到当前格子里的和解里的不一样,就会++cnt,这循环9次,或者在循环里时就超过限制,就退出了

这个就是判断当前是不是解

 就是说pre是记录上一次到这里来时的方向标号,就意味着不应该再走回去,如果走回去的话,就是先向上(下)走再向下(上)走,先向左(右)走再向右(左)走

可以人为定义状态移动数组,从而满足相反方向的序号具有一定关系

这里是使用对称数组排列,从而使相反方向的序号加和为数组长度-1

所以在递归判断中,是要判断pre+i==3,pre是上一个方向,i是这次选择的方向,加起来为3就是走了回去,需要被剪掉

这个操作虽然不能避免死循环的诞生,比如回字型循环,或者重复状态的出现(避免了只需两步的重复状态,但可能多步回到初始位置),但依然可以避免大量的两步重复

 这里是将输入的字符串(状态压缩的序列)转为矩阵,并得到0的位置

 

是把K作为外层循环,即直接建立在步数限制的基础上判断当前是不是能到达

#include<iostream>
#include<string>
#include<map>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;int read()
{int f=1,x=0;char ss=getchar();while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}return f*x;
}char ss[15];
int ans[4][4]=
{{0,0,0,0},{0,1,2,3},{0,8,0,4},{0,7,6,5}};
int a[5][5],k,judge;
int nxtx[]={0,1,-1,0};
int nxty[]={1,0,0,-1};int check()
{for(int i=1;i<=3;++i)for(int j=1;j<=3;++j)if(ans[i][j]!=a[i][j])return 0;return 1;
}int test(int step)
{int cnt=0;for(int i=1;i<=3;++i)for(int j=1;j<=3;++j)if(ans[i][j]!=a[i][j]){ if(++cnt+step>k) return 0;}return 1;
}void A_star(int step,int x,int y,int pre)
{if(step==k){ if(check())judge=1; return;}达到当前限制的最大深度if(judge) return;for(int i=0;i<4;++i){int nx=x+nxtx[i],ny=y+nxty[i];if(nx<1||nx>3||ny<1||ny>3||pre+i==3) continue;//加入了上述最优性剪枝swap(a[x][y],a[nx][ny]);if(test(step)&&!judge) A_star(step+1,nx,ny,i);//A*估价合法再向下搜索swap(a[x][y],a[nx][ny]);}
}int main()
{int x,y;scanf("%s",&ss);for(int i=0;i<9;++i){a[i/3+1][i%3+1]=ss[i]-'0';if(ss[i]-'0'==0)x=i/3+1,y=i%3+1;}if(check()){printf("0");return 0;}//特判不用移动while(++k)//枚举最大深度{A_star(0,x,y,-1);if(judge){printf("%d",k);break;}}return 0;
}

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

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

相关文章

FileUpload控件上传文件时出现 不支持给定路径的格式.的解决方法

正常代码&#xff0c;部署到server 2012时&#xff0c;在上传音频mp3文件时&#xff0c;显示错误“不支持给定路径的格式”&#xff0c;上传控件使用FileUpload控件&#xff1a; 因为程序之前是正常的&#xff0c;因此应该不是程序的问题。 上传时&#xff0c;发现在选择文件时…

深入浅出排序算法之归并排序

目录 1. 归并排序的原理 1.1 二路归并排序执行流程 2. 代码分析 2.1 代码设计 3. 性能分析 4. 非递归版本 1. 归并排序的原理 “归并”一词的中文含义就是合并、并入的意思&#xff0c;而在数据结构中的定义是将两个或者两个以上的有序表组合成一个新的有序表。 归并排序…

使用Packstack安装器安装一体化OpenStack云平台

【实训目的】 初步掌握OpenStack快捷安装的方法。掌握OpenStack图形界面的基本操作。 【实训准备】 &#xff08;1&#xff09;准备一台能够安装OpenStack的实验用计算机&#xff0c;建议使用VMware虚拟机。 &#xff08;2&#xff09;该计算机应安装CentOS 7&#xff0c;建…

电解电容寿命与哪些因素有关?

电解电容在各类电源及电子产品中是不可替代的元器件&#xff0c;这些电子产品中由于应用环境的原因&#xff0c;使它成为最脆弱的一环&#xff0c;所以&#xff0c;电解电容的寿命也直接影响了电子产品的使用寿命。 一、电解电容失效模式与因素概述 铝电解电容器正极、负极引出…

【Redis安装】Ubuntu和Centos

此处安装的是 Redis5 在 Ubuntu 系统上 切换到 root 用户下&#xff0c;su 命令切换使用 apt 可以搜索 redis 相关软件包 apt search redis使用 apt 命令安装 redis apt install redis手动修改配置文件 redis.conf cd /etc/redis/ vim redis.conf修改以下两处 重启服务器 …

【Opencv】OpenCV使用CMake和MinGW的编译安装出错解决

编译时出现的错误&#xff1a; mingw32-make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] Error 2 Makefile:161: recipe for target ‘all’ failed mingw32-make: *** [all] Error 2解决方法&#xff1a; 根据贴吧老哥的解答&#xff0c;发现是mingw版本有问题导…

Java基础篇 | Java8流式编程

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色专栏&#xf…

虚拟机使用linux常用问题(虚拟机操作系统:ubuntu 22.04LTS)

1.虚拟机连接外网 ubuntu解决网络连接的解决方案 CentOS7联网问题解决 明明连接好了但是没有网络的情况 2.虚拟机磁盘扩容 相关博客 利用gparted工具时,直接将unallocated空间的前一个位置的磁盘resize,将unallocated的空间全部覆盖 3.虚拟机与本机共享文件 安装vmtools 设…

Elasticsearch的聚集统计,可以进行各种统计分析

说明&#xff1a; Elasticsearch不仅是一个大数据搜索引擎&#xff0c;也是一个大数据分析引擎。它的聚集(aggregation)统计的REST端点可用于实现与统计分析有关的功能。Elasticsearch提供的聚集分为三大类。 度量聚集(Metric aggregation)&#xff1a;度量聚集可以用于计算搜…

嵌入式实时操作系统的设计与开发(互斥量学习)

一个无论多么小的系统&#xff0c;都会有大系统的缩影&#xff0c;就像俗话说“麻雀虽小五脏俱全”。 嵌入式实时操作系统中除了基本调度机制&#xff08;创建线程、调度线程、挂起线程等&#xff09;&#xff0c;事件处理机制&#xff08;中断管理、时钟管理&#xff09;、内…

【c++】运算符重载实例

重载自增自减运算符 Intger num(2); num; num;对自增运算符的重载要区分前置和后置。在重载之前需要思考一个问题&#xff0c;num是返回一个临时变量还是num对象的本体。 为了解决这个问题可以考虑实现一个Inc_()函数和_Inc()函数分别模仿后置和前置的行为 Integer Inc_(){i…

YOLOv5算法改进(20)— 如何去写YOLOv5相关的论文(包括论文阅读+规律总结+写作方法)

前言:Hello大家好,我是小哥谈。最近一直在阅读关于YOLOv5的相关论文,读着读着我发现一条可以发论文的规律,特此简单总结一下,希望能够对同学们有所启迪!🌈 前期回顾: YOLOv5算法改进(1)— 如何去改进YOLOv5算法

IO文件操作

小王学习录 今日鸡汤文件一. 文件路径1. 绝对路径2. 相对路径二. 文件类型三. 文件操作1. 文件系统操作2. 文件内容操作(字节流)1. 读文件2. 写文件3. 释放资源(.close)3. 文件内容操作(字符流)重识(System.in)今日鸡汤 光阴如骏马加鞭, 日月如落花流水. 文件 狭义上的文件:…

欧拉图和哈密顿图

欧拉图 在连通图G中&#xff0c;经过G的每条边一次且仅一次的通路&#xff0c;称为欧拉通路若欧拉通路为回路&#xff0c;则称为欧拉回路含有欧拉回路的图称为欧拉图有欧拉通路则G可以一笔画出有欧拉回路则G是连通的且无奇点&#xff08;欧拉图无奇点&#xff09; 哈密顿图 …

【MATLAB源码-第56期】基于WOA白鲸优化算法和PSO粒子群优化算法的三维路径规划对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1.粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;是一种模拟鸟群觅食行为的启发式优化方法。以下是其详细描述&#xff1a; 基本思想&#xff1a; 鸟群在寻找食物时&#xff0c;每只鸟都…

Kafka简单入门02——ISR机制

目录 ISR机制 ISR 关键概念 HW和LEO Java使用Kafka通信 Kafka 生产者示例 Kafka 消费者示例 ISR机制 Kafka 中的 ISR&#xff08;In-Sync Replicas&#xff09;机制是一种用于确保数据可靠性和一致性的重要机制。ISR 是一组副本&#xff0c;它包括分区的领导者&#xff…

【WinForm详细教程一】WinForm中的窗体、Label、TextBox及Button控件、RadioButton和CheckBox、ListBox

文章目录 1.WinForm文件结构2. 窗体的常用属性、方法与事件2.1 常用属性&#xff08;可直接在属性中设置&#xff09;2.2 常用方法2.3 常用事件 3.Label、TextBox及Button控件4.RadioButton和CheckBox5.ListBox&#xff08;列表框&#xff09; 1.WinForm文件结构 .sln文件 &am…

NFTScan | 10.16~10.22 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2023.10.16~ 2023.10.22 NFT Hot News 01/y00ts&#xff1a;迁移回以太坊的跨链桥已上线&#xff0c;将承担第一天所有 Gas 费 10 月 16 日&#xff0c;y00ts 发推称&#xff0c;将 y00…

scrapy的安装和使用

一、scrapy是什么&#xff1a;Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架&#xff0c;可以应用在包括数据挖掘&#xff0c;信息处理或存储历史数据等一系列的程序 二、scrapy的安装&#xff1a;pip install scrapy -i https://pypi.douban.com/…

vscode类似GitHub Copilot的插件推荐

由于GitHub Copilot前段时间学生认证的账号掉了很多&#xff0c;某宝激活也是价格翻了几倍&#xff0c;而却&#xff0c;拿来用一天就掉线&#xff0c;可以试试同类免费的插件哦。 例如&#xff1a;TabNine&#xff0c;下载插件后&#xff0c;他会提示你登录&#xff0c;直接登…