bfs搜索加记录路径

HDOJ-1043

  • 主要思路就是使用双向广度优先搜索,找最短路径。然后记录路径,找到结果是打印出来。
  • 使用康拓序列来来实现状态的映射。
  • 打印路径推荐使用vector最后需要使用algorithm里的reverse进行路径的翻转。
  • 注意本题有多组输入,这里的输入需要注意一下。
  • 如果题目没有要求最短路径,那么使用深搜的话也可以记录路径,这里也给出了代码。
  • 这里的记录路径的方法可以学习。还有判断没有解决方案的解决,利用逆序数。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
using namespace std;
const int maxn=362880;
int state[maxn][9];//从1开始
struct node{
int x;
int y;
int state;//编码
string s;
};
int fact[9];//阶乘
bool vis[maxn];
bool visr[maxn];
map<int,char> ma;
map<int,char> mar;
void init(){
fact[0]=1;
for(int i=1;i<=8;i++){
fact[i]=fact[i-1]*i;
}
ma[0]='u';mar[0]='d';
ma[1]='l';mar[1]='r';
ma[2]='d';mar[2]='u';
ma[3]='r';mar[3]='l';
}
int computeCon(string s){
int code=0;
for(int i=0;i<9;i++){
int cnt=0;
for(int j=i+1;j<9;j++){
if(s[j]-'0'<s[i]-'0')
cnt++;
}
code+=fact[8-i]*cnt;
}
return code;
}
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool in(int x,int y){
return x>=0&&x<3&&y>=0&&y<3;
}
string path[maxn];//-----------------------这种记录路径的方法很好----------------------------------
void bfs(string s,string final){
memset(vis,0,sizeof(vis));
memset(visr,0,sizeof(visr));
queue<node> q;
queue<node> q1;
int sx,sy;
for(int i=0;i<9;i++){
if(state[1][i]==0){
sx=i/3;
sy=i%3;
break;
}
}
int con=computeCon(s);
vis[con]=true;
node sta=node{sx,sy,con,s};
q.push(sta);
int conr=computeCon(final);
visr[conr]=true;
q1.push(node{2,2,conr,final});
path[con]="";
path[conr]="";
while(!q.empty()){
node temp=q.front();
q.pop();
//cout<<temp.state<<endl;
// if(temp.s==final){
// //print(temp.state);
// cout<<path[temp.state]<<endl;
// return true;
// }
for(int i=0;i<4;i++){
int tx=temp.x+dir[i][0];
int ty=temp.y+dir[i][1];
int newz=tx*3+ty;
int oldz=temp.x*3+temp.y;
if(in(tx,ty)){
string ns=temp.s;
ns[newz]=temp.s[oldz];
ns[oldz]=temp.s[newz];
int nowcon=computeCon(ns);
char direction=ma[i];
if(visr[nowcon]){
reverse(path[nowcon].begin(),path[nowcon].end());
cout<<path[temp.state]<<ma[i]<<path[nowcon]<<endl;
return;
}
if(!vis[nowcon]){
vis[nowcon]=1;
node now;
now.x=tx,now.y=ty,now.s=ns,now.state=nowcon;
q.push(now);
path[nowcon]=path[temp.state];
path[nowcon]+=direction;
//path[nowcon]=now;
//cout<<now.s<<endl;
}
}
}
temp=q1.front();
q1.pop();
for(int i=0;i<4;i++){
int tx=temp.x+dir[i][0];
int ty=temp.y+dir[i][1];
int newz=tx*3+ty;
int oldz=temp.x*3+temp.y;
if(in(tx,ty)){
string ns=temp.s;
ns[newz]=temp.s[oldz];
ns[oldz]=temp.s[newz];
int nowcon=computeCon(ns);
char direction=mar[i];
if(vis[nowcon]){
reverse(path[temp.state].begin(),path[temp.state].end());
cout<<path[nowcon]<<mar[i]<<path[temp.state]<<endl;
return;
}
if(!visr[nowcon]){
visr[nowcon]=1;
node now;
now.x=tx,now.y=ty,now.s=ns,now.state=nowcon;
q1.push(now);
path[nowcon]=path[temp.state];
path[nowcon]+=direction;
//path[nowcon]=now;
//cout<<now.s<<endl;
}
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
init();
char c;
while(cin>>c){
string s="";
if(c=='x')
state[1][0]=0;
else state[1][0]=c-'0';
s+=(state[1][0]+'0');
for(int i=1;i<=8;i++){
cin>>c;
if(c=='x')
state[1][i]=0;
else state[1][i]=c-'0';
s+=(state[1][i]+'0');
}
//cout<<s<<endl;
string final="123456780";
int k=0;
for(int i=0;i<9;i++){
if(!state[1][i])
continue;
for(int j=i+1;j<9;j++){
if(state[1][j]<state[1][i]&&state[1][j]){
k++;
}
}
}
if(k&1){
cout<<"unsolvable"<<endl;
continue;
}
bfs(s,final);
}
return 0;
}

这里是未Ac超时了的代码,而且记录路径的方法没有上面好。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
using namespace std;
const int maxn=362880;
int state[maxn][9];//从1开始
struct node{
int x;
int y;
int state;//编码
int father;
char direction;
string s;
};
int fact[9];//阶乘
bool vis[maxn];
map<int,char> ma;
map<string,int> conma;
void init(){
fact[0]=1;
for(int i=1;i<=8;i++){
fact[i]=fact[i-1]*i;
}
ma[0]='u';
ma[1]='l';
ma[2]='d';
ma[3]='r';
}
int computeCon(string s){
int code=0;
for(int i=0;i<9;i++){
int cnt=0;
for(int j=i+1;j<9;j++){
if(s[j]-'0'<s[i]-'0')
cnt++;
}
code+=fact[8-i]*cnt;
}
return code;
}
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool in(int x,int y){
return x>=0&&x<3&&y>=0&&y<3;
}
node path[maxn];
void print(int state){
vector<char> v;
//cout<<state<<endl;
while(path[state].direction!='n'){
//cout<<state<<endl;
v.push_back(path[state].direction);
state=path[state].father;
}
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++){
cout<<v[i];
}
cout<<endl;
}
bool bfs(string s,string final){
memset(vis,0,sizeof(vis));
queue<node> q;
int sx,sy;
for(int i=0;i<9;i++){
if(state[1][i]==0){
sx=i/3;
sy=i%3;
break;
}
}
int con=computeCon(s);
vis[con]=true;
node sta=node{sx,sy,con,-1,'n',s};
q.push(sta);
path[con]=sta;
while(!q.empty()){
node temp=q.front();
q.pop();
//cout<<temp.state<<endl;
if(temp.s==final){
print(temp.state);
return true;
}
for(int i=0;i<4;i++){
int tx=temp.x+dir[i][0];
int ty=temp.y+dir[i][1];
int newz=tx*3+ty;
int oldz=temp.x*3+temp.y;
if(in(tx,ty)){
string ns=temp.s;
ns[newz]=temp.s[oldz];
ns[oldz]=temp.s[newz];
int nowcon=computeCon(ns);
if(!vis[nowcon]){
vis[nowcon]=1;
node now;
char direction=ma[i];
now.x=tx,now.y=ty,now.father=temp.state,now.direction=direction,now.s=ns,now.state=nowcon;
q.push(now);
path[nowcon]=now;
//cout<<now.s<<endl;
}
}
}
}
return false;
}
int main(){
init();
char c;
while(cin>>c){
string s="";
if(c=='x')
state[1][0]=0;
else state[1][0]=c-'0';
s+=(state[1][0]+'0');
for(int i=1;i<=8;i++){
cin>>c;
if(c=='x')
state[1][i]=0;
else state[1][i]=c-'0';
s+=(state[1][i]+'0');
}
//cout<<s<<endl;
string final="123456780";
if(!bfs(s,final)){
cout<<"unsolvable"<<endl;
}
}
return 0;
}

HDOJ-1043 Eight(八数码问题+双向bfs+高效记录路径+康拓展开)的更多相关文章

  1. hdu 1043 Eight (八数码问题)【BFS】+【康拓展开】

    <题目链接> 题目大意:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 解题分析:本题用BFS来寻找路径,为 ...

  2. 八数码问题 双向BFS/Hsh链表存储

    转自洛谷 作者EndSaH #include<iostream> #include<string> #include<cmath> #include<cstr ...

  3. cdoj 414 八数码 (双向bfs+康拓展开,A*)

    一道关乎人生完整的问题. DBFS的优越:避免了结点膨胀太多. 假设一个状态结点可以扩展m个子结点,为了简单起见,假设每个结点的扩展都是相互独立的. 分析:起始状态结点数为1,每加深一层,结点数An ...

  4. HDU 1043 Eight 八数码问题 A*算法(经典问题)

    HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...

  5. Hdu 1043 Eight (八数码问题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目描述: 3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动 ...

  6. HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法

    先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...

  7. Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

  8. hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数

    题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...

  9. 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开

    [kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...

随机推荐

  1. P3376 【模板】网络最大流——————Q - Marriage Match IV(最短路&最大流)

    第一道题是模板题,下面主要是两种模板,但都用的是Dinic算法(第二个题也是) 第一题: 题意就不需要讲了,直接上代码: vector代码: 1 //invalid types 'int[int]' ...

  2. Linux运维博客大全

    系统 U盘安装Linux详细步骤_hanxh7的博客-CSDN博客_u盘安装linux 使用U盘安装linux系统 - lwenhao - OSCHINA 各厂商服务器存储默认管理口登录信息(默认IP ...

  3. Kubernets二进制安装(3)之准备签发证书环境

    1.在mfyxw50机器上分别下载如下几个文件:cfssl.cfssl-json.cfssl-certinfo cfssl下载连接地址: https://pkg.cfssl.org/R1.2/cfss ...

  4. c# 类(4)

    原文链接:https://csharp.net-tutorials.com/classes/visibility/ 可见性 Visibility 可见性 控制的是 访问权限的问题.最常见的就是priv ...

  5. 全局ID生成--雪花算法改进版

    存在的问题 时间回拨问题:由于机器的时间是动态的调整的,有可能会出现时间跑到之前几毫秒,如果这个时候获取到了这种时间,则会出现数据重复 机器id分配及回收问题:目前机器id需要每台机器不一样,这样的方 ...

  6. 9. Lock wait timeout exceeded

    一. 现象 用户打开消息推送有概率报错,后续发现推送消息阅读数.点赞数无法正常更新,mysql报警有行锁, DBA抓到有锁表语句,kill该语句未正常恢复,elk日志有大量的java.sql.SQLE ...

  7. js load more select

    js load more select searchable scroll load more append to list refs xgqfrms 2012-2020 www.cnblogs.co ...

  8. Java REPL & JShell

    Java REPL & JShell Java 11 JShell Java Shell https://www.infoq.com/articles/jshell-java-repl/ Th ...

  9. Google Meet & gmail & video conference

    Google Meet & gmail & video conference Conv-2019 & live stream Google Meet https://meet. ...

  10. SameSite & Cookies

    SameSite & Cookies SameSite=None && Secure (HTTPS) https://developer.mozilla.org/en-US/d ...