洛谷 P1379 八数码难题
2017-08-10 13:33
253 查看
啊!!这一题算是BFS中的经典了,如果你不懂BFS的话,可以睡觉了~~~
现在请大家跳转题面
啊!!现在我们来分析一下思路
1.使用3*3的数组存储,操作十分简单,但会超时很多点,有兴趣的读者可以自行尝试一下;
2.程序中用3*3的二维数组表示布局比较直观,但在判断重复,判断是否达到目标方面,却给程序增加了复杂性,也影响了运行速度。可以改用字符串形式来表示布局,第1..3个数表示第一行的三个数,第4..6个数,表示第二行的三个数,第7..9个数表示第三行的三个数。这样,程序的判断和判重可以方便很多。
但如判重时使用的是一个存下所有情况的数组,那也能拿10分。
如:10分代码
现在我们发现判重的时候浪费了许多时间,所以我们可使用MAP或康托展开
100分(MAP)
现在请大家跳转题面
题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据) 输入输出样例 输入样例#1: 283104765 输出样例#1: 4
啊!!现在我们来分析一下思路
1.使用3*3的数组存储,操作十分简单,但会超时很多点,有兴趣的读者可以自行尝试一下;
2.程序中用3*3的二维数组表示布局比较直观,但在判断重复,判断是否达到目标方面,却给程序增加了复杂性,也影响了运行速度。可以改用字符串形式来表示布局,第1..3个数表示第一行的三个数,第4..6个数,表示第二行的三个数,第7..9个数表示第三行的三个数。这样,程序的判断和判重可以方便很多。
但如判重时使用的是一个存下所有情况的数组,那也能拿10分。
如:10分代码
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<string> using namespace std; int hash1=1,f[51000]; string go,to,hashb[51000],ans[51000]; int h=0,t=1; int a[4]={1,-1,0,0}, b[4]={0,0,1,-1}; int out(int t) { int s=0; do{s++; t=f[t]; }while(f[t]!=0); return s; } int pz(int n) { for(int i=1;i<=n;i++) if(hashb[i]==ans[h]) return 0; return 1; } int bfs() { ans[1]=go;f[1]=0; do{int i; h++; for( i=0;i<=8;i++) if(ans[h][i]=='0') break; for(int x=0;x<4;x++) { int nowx,nowy,tox,toy,wz; nowx=i/3+1; nowy=i%3+1; tox=nowx+a[x]; toy=nowy+b[x]; wz=(tox-1)*3+toy-1; if(tox>=1&&tox<=3&&toy>=1&&toy<=3&&wz>=0&&wz<=8&&nowx>=1&&nowx<=3&&nowy>=1&&nowy<=3) { char c; c=ans[h][wz]; ans[h][wz]=ans[h][i]; ans[h][i]=c; if(pz(hash1)==1) { t++;ans[t]=ans[h]; f[t]=h; hashb[++hash1]=ans[t]; if(ans[t]==to) {return out(t);} } c=ans[h][i]; ans[h][i]=ans[h][wz]; ans[h][wz]=c; } } }while(h<t); } int main() { cin>>go; hashb[1]=go; to="123804765"; int answer; answer=bfs(); printf("%d",answer); return 0; }
现在我们发现判重的时候浪费了许多时间,所以我们可使用MAP或康托展开
100分(MAP)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<map> using namespace std; int hash1=1,f[510000]; string go,to,ans[510000]; int h=0,t=1; int a[4]={1,-1,0,0}, b[4]={0,0,1,-1}; map<string,int>hashb; int out(int t) { int s=0; do{s++; t=f[t]; }while(f[t]!=0); return s; } int bfs() { ans[1]=go;f[1]=0; do{int i; h++; for( i=0;i<=8;i++) if(ans[h][i]=='0') break; for(int x=0;x<4;x++) { int nowx,nowy,tox,toy,wz; nowx=i/3+1; nowy=i%3+1; tox=nowx+a[x]; toy=nowy+b[x]; wz=(tox-1)*3+toy-1; if(tox>=1&&tox<=3&&toy>=1&&toy<=3&&wz>=0&&wz<=8&&nowx>=1&&nowx<=3&&nowy>=1&&nowy<=3) { char c; c=ans[h][wz]; ans[h][wz]=ans[h][i]; ans[h][i]=c; if(hashb[ans[h]]!=1) { t++;ans[t]=ans[h]; f[t]=h; hashb[ans[h]]=1; if(ans[t]==to) {return out(t);} } c=ans[h][i]; ans[h][i]=ans[h][wz]; ans[h][wz]=c; } } }while(h<t); } int main() { cin>>go; hashb[go]=1; to="123804765"; int answer; answer=bfs(); printf("%d",answer); return 0; }
相关文章推荐
- codevs1225 八数码难题 bfs+哈希
- wikioi1225 八数码难题
- Codevs 1225 八数码难题
- 八数码难题 洛谷1379
- 洛谷P1379 八数码难题
- 【宽搜】【A星】八数码难题 WikiOI 1225 Astar
- 八数码难题
- Codevs 1225 八数码难题
- 八数码难题
- IDA*——Luogu1379 八数码难题
- codevs 1225_八数码难题_bfs+hash
- 1225 八数码难题
- 【基础练习】【BFS+A*】codevs1225八数码难题题解
- BFS+康托展开(洛谷1379 八数码难题)
- 八数码难题
- P1379 八数码难题
- 八数码难题(转)
- 八数码难题(启发式搜索)
- 八数码难题 hdu1043/ poj1077
- ## 八数码难题 ##