洛谷 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来去重,在这里只需要一个队列,因为需要较少步数达到的状态一定在步数较多的状态之前入队列. # ...
随机推荐
- SpringMVC核心
DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,与spring IoC容器无缝集成. 主要用作职责调度工作,本身主要用于 ...
- .NET配置问题
Ext.NET MVC 配置问题总结 随着VS版本和.NET MVC版本.EF的版本的不断更新,虽然很多功能随着版本的提升而更完善,但对于旧版本开发的软件就有点悲催了,或许很多开发者都遇到 ...
- Maven项目工程目录
maven工程目录规范: src/main/java 存放项目的.java文件 src/main/resources 存放项目的资源文件,如spring.hibernate配置文件 src/t ...
- Web系统测试的常用方法总结-18《转载》
Web系统测试的常用方法归纳 --- 知识记录 1.页面链接检查 每一个链接是否都有对应的页面,并且页面之间切换正确.可以依靠一些工具,如:LinkBotPro.File-AIDCS.HTML Lin ...
- BZOJ 2744
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #incl ...
- SpringMVC原理及流程解析
前言 春节期间宅在家里闲来无事,对SpringMVC进行了比较深入的了解,将之前模糊不清的地方基本摸索清楚了,特此撰文总结记录一下. 正文 一.一个请求为什么会调用到SpringMVC框架里? 首先问 ...
- abstract和interface关键字介绍
一.abstract关键字介绍 abstract可以修饰方法.类.使用abstract修饰的方法和类分别叫做抽象方法和抽象类. 1.抽象方法 抽象方法的定义:指可以通过abstract关键字声明的方法 ...
- 下载jQuery
下载jQuery :https://jquery.com/download/ . 将下载好的文件放到项目中 引入到代码中 <script type="text/javascript&q ...
- POJ-3262 贪心的一个小技巧
Protecting the Flowers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 3204 Accepted: ...
- RGB转到HSV色彩空间转换
原文链接:https://blog.csdn.net/lsg19920625/article/details/78416649