poj 1077 zoj 1217 hdu 1043 八数码
来源:互联网 发布:婚庆域名 编辑:程序博客网 时间:2024/06/05 08:55
poj 1077 zoj 1217 hdu 1043 八数码
题意:以sample为例
将 2 3 4 1 2 3
1 5 x —> 4 5 6
7 6 8 7 8 x
x可以与上下左右交换,问最少的交换次数到达
上例的答案是: ullddrurdllurdruldr
不过我程序运行的答案是:ullddrurdllurrdlurd
虽然结果不同,但是答案也是正确的,因为只要输出一个路径
下面说一下我的做法:
我将3*3的矩阵压缩成一个数,x用0表示,状态总共有9!=362880种,我用一个数组记录,查找时用二分查找,(刚刚华爷(搜索神牛)告诉我只要hash mod1000007
刚刚好所有的数字都不会有重合的,这就是八数码一个神奇的地方,大家可以去试试)
用bfs从123456780 扩展下去->123450786和123456708,直到队列空为止,记得要记录路径。
1077Accepted14116K391MSG++3147B
Accepted 1217C++22016068
Accepted1043125MS14360K3331 BC++
看来hdu的服务器是最快的
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define N 1000000const int n = 9;int memory[N],top;int a[n],b[n],p[n];int maze[n+1][n+1];void init(){ top=0; p[0] = 1; for(int i=1;i<n;i++) p[i] = p[i-1] * 10; b[n-1] = 1; for(int i=n-2;i>=0;i--) b[i] = b[i+1] *10; for(int i=0;i<n;i++) a[i] = i; do { int sum=0; for(int i=0;i<n;i++) sum += a[i]*b[i]; memory[top++] = sum; }while(next_permutation(a,a+n)); memset(maze,0,sizeof(maze)); for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) maze[i][j]=1;}struct node{ int to,turn;}path[N];int mark[N];struct info{ int x,index,pos;};int dx[]={-1,0,1,0};int dy[]={0,1,0,-1};int ad[]={-3,1,3,-1};int pu[]={3,-1,-3,1};int turnx[] = {1,1,1,2,2,2,3,3,3};int turny[] = {1,2,3,1,2,3,1,2,3};int turn(int k,int index,int x){ int ret; int x1,x2; x1 = x/b[index]%10; x2 = x/b[index+ad[k]]%10; ret = x - x1*b[index] - x2*b[index+ad[k]] + x1*b[index+ad[k]] + x2*b[index]; return ret;}int ll;void bfs(){ memset(path,-1,sizeof(path)); memset(mark,0,sizeof(mark)); queue<struct info> q; struct info tmp1,tmp2; int l,r,sum = 0; for(int i=1;i<n;i++) sum += i*b[i-1]; tmp1.x = sum; tmp1.index = 8; ll=l = lower_bound(memory,memory+top,sum) - memory; tmp1.pos=l; mark[l] = 1; q.push(tmp1); while(!q.empty()) { tmp1 = q.front(); q.pop(); int xx = turnx[tmp1.index], yy = turny[tmp1.index]; for(int k=0;k<4;k++) { int x = xx +dx[k],y = yy + dy[k]; if(maze[x][y]) { tmp2.x = turn(k,tmp1.index ,tmp1.x); l = lower_bound(memory,memory+top,tmp2.x)-memory; if(mark[l]==0) { tmp2.index = tmp1.index + ad[k]; tmp2.pos = l; path[l].turn = k; path[l].to = tmp1.pos; q.push(tmp2); mark[l] = 1; } } } }}int main(){// freopen("in","r",stdin); init(); bfs(); int sum=0,l; char ch; while(cin>>ch) { if(ch!='x') sum = (ch-'0')*b[0]; else sum = 0; for(int i=1;i<n;i++) { cin>>ch; if(ch == 'x') continue; sum += (ch - '0') * b[i]; } l = lower_bound(memory,memory+top,sum) - memory; if(mark[l]==0) printf("unsolvable"); else { while(l!=ll) { if(path[l].turn==0) putchar('d'); else if(path[l].turn==1) putchar('l'); else if(path[l].turn==2) putchar('u'); else putchar('r'); l=path[l].to; } } printf("\n"); } return 0;}
- poj 1077 zoj 1217 hdu 1043 八数码
- 八数码A*【POJ-1077 HDU-1043】
- poj 1077 hdu 1043 八数码
- bfs+hash poj 1077/hdu 1043 八数码问题
- hdu 1043 poj 1077 Eight Time (搜索&八数码)
- HDU 1043 / POJ 1077 Eight(八数码问题)
- HDU 1043 Eight poj 1077 (八数码 启发式搜索)
- POJ 1077(HDU 1043)Eight(八数码DBFS)
- 八数码(POJ-1077或HDU-1043)
- poj 1077 八数码
- poj 1077 八数码
- poj 1077 八数码
- uva 652---Eight Poj 1077 ---Eight zoj 1217---Eight (八数码解法2)
- uva 652---Eight Poj 1077 ---Eight zoj 1217---Eight (八数码解法1)
- uva 652---Eight Poj 1077 ---Eight zoj 1217---Eight (八数码解法3)
- HDU 1043 八数码
- HDU 1043 Eight(经典八数码问题)对比POJ 1077(bfs)
- hdu 1043 /poj 1077 Eight(经典八数码问题,BFS+康托展开)
- Chromium MessageLoop类分析
- Ubuntu下 git 服务器的搭建
- Sql语句筛选出所有某【字段值重复】的记录!
- 使用数组时注意的一些问题
- Chrome的线程体系
- poj 1077 zoj 1217 hdu 1043 八数码
- PHP添加uuid()模块支持
- ASP.NET弹出提示框
- 2012年9月开学季CSDN高校俱乐部专家巡讲讲师招募
- oracle 卸载
- DVI
- struts2的s:iterator 标签 详解
- WEB项目(B/S系统)打包安装(总结篇)
- 图片滚动