洛谷 P1379 八数码难题
来源:互联网 发布:周末网络国债理财申请 编辑:程序博客网 时间:2024/06/13 00:00
啊!!这一题算是BFS中的经典了,如果你不懂BFS的话,可以睡觉了~~~
现在请大家跳转题面
题目描述在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;}
阅读全文
1 0
- 洛谷P1379 八数码难题
- 洛谷 P1379 八数码难题
- 洛谷 P1379 八数码难题
- 洛谷 P1379 八数码难题
- 洛谷 P1379 八数码难题
- 洛谷 P1379 八数码难题
- P1379 八数码难题
- P1379 八数码难题
- IDA*-洛谷P1379 八数码难题
- C++ P1379 八数码难题
- 八数码难题 洛谷1379
- 八数码难题源代码
- 【宽搜】八数码难题
- wikioi1225 八数码难题
- wikioi1225 八数码难题
- ## 八数码难题 ##
- Codevs1225 八数码难题
- 八数码难题
- 前台JSON对象和JSON字符串互转
- 二叉树的建立与遍历详解 菜鸟都能看懂的教程
- aliyun的centOS的yum源地址
- 应届毕业生如何通过学习Linux系统选择一份高薪职业
- days3
- 洛谷 P1379 八数码难题
- CentOS 7.2 安装配置Samba服务器
- MP4文件点播seek原理
- int,long,long long等类型的范围
- iOS Analyse 静态分析记录
- 打字时如何正确放置手指 正确的键盘打字手势
- Qt 隐藏选中虚线框
- 在我国多长时间才算劳动关系?
- js 实现刷新页面后回到记录时滚动条的位置