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. Codeforces Round #647 (Div. 2) C. Johnny and Another Rating Drop(数学)

    题目链接:https://codeforces.com/contest/1362/problem/C 题意 计算从 $0$ 到 $n$ 相邻的数二进制下共有多少位不同,考虑二进制下的前导 $0$ .( ...

  2. 放苹果 POJ - 1664 递推

    把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. Input 第一行是测试数据的数目t(0 <= t < ...

  3. Codeforces Round #643 (Div. 2) D. Game With Array (思维,构造)

    题意:给你两个正整数\(N\)和\(S\),构造一个长度为\(N\)并且所有元素和为\(S\)的正整数数组,问是否能找到一个\(K (0\le K \le S)\)使得这个数组的任意_子数组_的和都不 ...

  4. 已处理证书链,但是在不受信任提供程序信任的根证书中终止 - Windows 7安装.Net Framework 4.6.2时出现此问题

    https://blog.csdn.net/inchat/article/details/104294302

  5. codeforce 855B

    B. Marvolo Gaunt's Ring time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  6. Kafka 博文索引

    博文索引 KafkaBroker 简析 KafkaConsumer 简析 KafkaProducer 简析 KafkaMirrorMaker 的不足以及一些改进 Kafka 简介 数据是系统的燃料,系 ...

  7. js class static property & public class fields & private class fields

    js class static property class static property (public class fields) const log = console.log; class ...

  8. setTimeout 实现原理, 机制

    setTimeout 实现原理, 机制 JS 执行机制说起 浏览器(或者说 JS 引擎)执行 JS 的机制是基于事件循环. 由于 JS 是单线程,所以同一时间只能执行一个任务,其他任务就得排队,后续任 ...

  9. Raspberry Pi & Node.js & WebSockets & IM

    Raspberry Pi & Node.js & WebSockets & IM Raspberry Pi 4 nvm & node.js $ curl -o- htt ...

  10. how to overwrite css !important style

    how to overwrite css !important style css !important bug how to override css !important style https: ...