洛谷 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来去重,在这里只需要一个队列,因为需要较少步数达到的状态一定在步数较多的状态之前入队列. # ...
随机推荐
- 【LeetCode 】验证回文串
[问题]给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写.说明:本题中,我们将空字符串定义为有效的回文串. 示例 : 输入: "A man, a plan, a ...
- Nginx+uwsgi+django部署项目
nginx把请求转发给uwsgi,然后把uwsgi处理得到的结果返回给浏览器. 安装nginx: yum -y install gcc pcre-devel openssl-devel #安装Ngin ...
- oracle基础知识小结
一.查看oracle用户.角色信息1.查看所有用户 select * from all_users; select * from user_users; 2.查看用户或角色系统权限 select * ...
- 001、在本地搭建SAP虚拟机环境,用于各种暴力操作
一.在某网盘下载一个SAP虚拟机,用于SAP学习和相关的测试.打开图中的服务器,点击运行,等灯都变成绿色 二.点击打开熟悉的SAP登录图标 三.很完美的运行起来了. 友情提示:SAP对电脑配置要求挺高 ...
- 十九、JavaScript之数组
一.代码如下 二.执行效果如下 <!DOCTYPE html> <html> <meta http-equiv="Content-Type" cont ...
- Spring配置数据源的三种方法
前言:今天接触新项目发现用的是JNDI配置数据源,用度娘倒腾了一会也没弄好,只好用平常用的方法,结果发现BasicDataSource和DriverManagerDataSource也是不同的,所以记 ...
- HDU_4912 Path on the tree 2014多校5 贪心+LCA
当时刚学LCA-tarjan不久,就比赛有这个题,但没想到还是没做出来..一开始以为是DP来着,没想到是贪心,想想也对,从树的最下层开始,每次遇到询问的点,就找到他们的LCA(路径里面必经LCA),然 ...
- 关于c++静态类的说法
看了网上的观点,大致有这几种比较好的. 观点一:根据现代的C++观点,静态类没有必要存在于C++中. 一个类是对一个概念的描述,类的本质是它维护了一个不变式,也就是说它有一个状态,它所有的接口都是为了 ...
- 倍增求LCA(最近公共祖先)
P3379 [模板]最近公共祖先(LCA) 题目描述: 读入一棵以1为根的树,q次询问,每次给定x和y,问x和y的最近公共祖先是哪一个节点. 树的读入格式:n-1行每行两个整数x.y,表示一条连接x和 ...
- P 1021 个位数统计
转跳点: