洛谷 P1379 八数码难题(map && 双向bfs)
题目传送门
解题思路:
一道bfs,本题最难的一点就是如何储存已经被访问过的状态,如果直接开一个bool数组,空间肯定会炸,所以我们要用另一个数据结构存,STL大法好,用map来存,直接AC.
AC代码:
- #include<cstdio>
- #include<iostream>
- #include<map>
- #include<queue>
- using namespace std;
- int a[][],n;
- int ans = ;
- const int dx[]={-,,,},dy[]={,-,,};
- map<int,int> m;
- inline void bfs() {
- queue<long long> q;
- q.push(n);
- m[n] = ;
- while(!q.empty()) {
- int u = q.front();
- q.pop();
- int x = ,y= ,n = u;
- if(u == ans) break;
- for(int i = ;i >= ; i--)
- for(int j = ;j >= ; j--) {
- a[i][j] = n % ;
- n /= ;
- if(!a[i][j]) x = i,y = j;
- }
- for(int i = ;i < ; i++) {
- int nx = x + dx[i],ny = y + dy[i],ns = ;
- if(nx < || ny < || nx > || ny > ) continue;
- swap(a[nx][ny],a[x][y]);
- for(int i = ;i <= ; i++)
- for(int j = ;j <= ; j++)
- ns = ns * + a[i][j];
- if(!m.count(ns)) {
- m[ns] = m[u] + ;
- q.push(ns);
- }
- swap(a[nx][ny],a[x][y]);
- }
- }
- }
- int main()
- {
- scanf("%d",&n);
- bfs();
- printf("%d",m[]);
- return ;
- }
普通bfs
emmm,虽然普通bfs能A,但还是感觉太慢,所以试了一下双向bfs.
- #include<cstdio>
- #include<iostream>
- #include<queue>
- #include<map>
- using namespace std;
- int a[][],n,n1 = ;
- int x,y;
- int wayx[] = {,-,,},wayy[] = {,,,-};
- map<int,int> p,sum;
- inline void juzhen(int o) {
- for(int i = ;i >= ; i--)
- for(int j = ;j >= ; j--) {
- a[i][j] = o % ;
- o /= ;
- if(a[i][j] == ) x = i,y = j;
- }
- }
- inline void double_bfs() {
- if(n1 == ) return ;
- queue<int> step[];
- step[].push(n);
- step[].push(n1);
- sum[n] = ;
- sum[n1] = ;
- p[n] = ;p[n1] = ;
- int deep = ,s;
- while(!step[].empty() || !step[].empty()) {
- int i = ;
- while(i < ) {
- if(sum[step[i].front()] != deep) {
- i++;
- continue;
- }
- s = step[i].front();
- step[i].pop();
- juzhen(s);
- for(int w = ;w < ; w++) {
- int xx = x + wayx[w];
- int yy = y + wayy[w];
- if(xx < || xx > || yy < || yy > ) continue;
- swap(a[x][y],a[xx][yy]);
- int pp = ;
- for(int j = ;j <= ; j++)
- for(int u = ;u <= ; u++)
- pp = pp * + a[j][u];
- if(p.count(pp)) {
- if(p[pp] == - i) {
- if(p[pp] == )
- printf("%d",(deep + ) * );
- else
- printf("%d",deep * + );
- return ;
- }
- }
- else {
- step[i].push(pp);
- sum[pp] = sum[s] + ;
- p[pp] = i;
- }
- swap(a[x][y],a[xx][yy]);
- }
- }
- deep++;
- }
- }
- inline void tepan() {
- if(n == n1) printf("");
- if(n == n1) n = n1 = ;
- }
- int main()
- {
- scanf("%d",&n);
- tepan();
- double_bfs();
- return ;
- }
双向bfs
双向bfs确实快很多很多,普通bfs耗时7.38s,而双向bfs只耗时291ms,快了25倍!!!!!!
洛谷 P1379 八数码难题(map && 双向bfs)的更多相关文章
- 洛谷——P1379 八数码难题
P1379 八数码难题 双向BFS 原来双向BFS是这样的:终止状态与起始状态同时入队,进行搜索,只不过状态标记不一样而已,本题状态使用map来存储 #include<iostream> ...
- 洛谷 P1379 八数码难题 解题报告
P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...
- 洛谷P1379八数码难题
题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...
- 洛谷 P1379 八数码难题 Label:判重&&bfs
特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给 ...
- 洛谷P1379 八数码难题
传送门 1.先用dfs枚举9!的全排列,存到hash数组里(类似离散化),因为顺序枚举,就不需要排序了 2.朴素bfs,判重就用二分找hash:如果发现当前状态=要求状态,输出步数结束程序 上代码 # ...
- 洛谷—— P1379 八数码难题
https://daniu.luogu.org/problem/show?pid=1379 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示 ...
- 洛谷 P1379 八数码难题
题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了 ...
- 洛谷 - P1379 - 八数码难题 - bfs
https://www.luogu.org/problemnew/show/P1379 #include <bits/stdc++.h> using namespace std; #def ...
- 洛谷 P1379 八数码难题 题解
我个人感觉就是一道bfs的变形,还是对bfs掌握不好的人有一定难度. 本题思路: 大体上用bfs搜,用map来去重,在这里只需要一个队列,因为需要较少步数达到的状态一定在步数较多的状态之前入队列. # ...
随机推荐
- Linux学习《第四章脚本》20200222
- JS - n次方计算
pow 方法返回底表达式的指定次幂. Math.pow(base, exponent) 参数base 必选项.表达式底的值. exponent 必选项.表达式的指数值.
- 留学论文Results部分英文写作句型整理
本文分享曼切斯特大学全校语言项目负责人约翰·莫莱博士(Dr John Morley)给出的与结果介绍相关的句型,小编为大家整理了一下一共分为了11类,看完之后觉得非常有用,这里分享给大家,各位留学小伙 ...
- 二、【未来】React环境安装:npx
搭建React的开发环境的第二种方法(新-未来推荐): https://reactjs.org/docs/create-a-new-react-app.html 一. npx简介: 1. npm v5 ...
- spring源码 继承AttributeAccessor的BeanDefinition接口
/** * A BeanDefinition describes a bean instance, which has property values, * constructor argument ...
- 第一部分 JavaScript语言核心(三)
第六章 对象 P123 在ES3中,点运算符后的标识符不能是保留字.如果一个对象的属性名是保留字,name必须使用方括号的形式访问它们,如o["for"]和o["clas ...
- office(CVE-2012-0158)漏洞分析报告
2019/9/12 1.漏洞复现 ①发现崩溃 ②找到漏洞所在的函数,下断点,重新跑起来,单步调试,找到栈被改写的地方 ③分析该函数 把MSCOMCTL拖入IDA,查看该函数代码 ④查看调用栈,回溯. ...
- Tornado中的Cookie设置
Tornado中的cookie分为两种--普通cookie和安全cookie 普通cookie 1.创建cookie 原型 self.set_cookie(name, value, domain=No ...
- sqlserver 联接查询的一些注意点
1.内连接的安全性 (1) inner join 是ANSI SQL-92 语法.等值联接是ANSI SQL-89 的语法 ,两者已相同方式解释.在性能上没有差别 (2)但是强烈建议使用ANSI SQ ...
- Win7 node多版本管理gnvm采坑记录
采坑描述:下载新node版本及切换node失败 解决:1.要用管理员权限启动cmd:2.确保node是空闲的 Gnvm下载地址: 32-bit | 64-bit Github 1.下载之后为 得到一个 ...