Hdu 1043
来源:互联网 发布:usb摄像头和网络摄像头 编辑:程序博客网 时间:2024/06/05 18:00
经典的八数码问题。
这个A*写的比较详细。
某位神牛曾说过,此题是涉及到人生完不完整的一道题。。
Goodness大牛曾总结了 八数码的八重境界 : http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html
足见此题的重要性。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043
本人不才,只写出了其中几个。。
1、 暴搜+离散+二分
一直以来没用过hash表,这次首先想到的也是二分,先dfs找出所有状态36w+,然后离散化,之后就可以进行暴搜了,hdu TLE,pku500ms。。
2、 单广预处理
上网搜了下,发现逆序数hash要快好多, 以n!为基数,以当前位置的逆序数为系数构造hash表,则123456789对应的hash值为0,987654321对应的
hash值为:0*0!+1*1!+2*2!+3*3!+4*4!+5*5!+6*6!+7*7!+8*8!= 9!-1; 每一种状态刚好对应唯一的hash值。具体的原因可以去查查一些数学书。。
从目标状态搜能到达的所有状态,把能到达的状态标记下来,对于每一个输入的实例,耗时O(1); hdu 78ms, pku 250ms
3、A*+哈希+曼哈顿距离
第一次写A*发现A*也不是传说中的那么难, 关键是要找到启发式函数,对于此题,曼哈顿距离就是一个很不错的启发式函数。所谓曼哈顿距离即是
两个点上在标准坐标系上的绝对轴距总和,|x1-x2|+|y1-y2|; 另外对于无解的情况要首先判断出来: 求出不算x的时候的所有逆序数总和, 如果这个数
是奇数的话就无解, 至于你看没看出来,反正我是没看出来。。。 hdu 671ms, pku 32ms
4、IDA*+曼哈顿距离
感觉A*和IDA*差不多,只不过一个用于广搜,一个用于深搜。。。 IDA*是先找到到达目标状态至少需要多少步,然后迭代加深, 对其进行剪枝。。hdu 1s+,pku 47ms
贴一个A*代码:
# include<stdio.h># include<string.h># include<queue># define N 363000using namespace std;bool visit[N];char visit1[N];int pre[N],st,a[10],end; int dir[9]={1,1,2,6,24,120,720,5040,40320};struct node{ int ma[10]; int ans1; int x; int f; int g; bool operator <(const node &a)const { return a.f < f;//优先访问f较小者 }};int hash(int s[]){ int i,j,cnt,sum; sum=0; for(i=1;i<=9;i++) { cnt=0; for(j=1;j<i;j++) if(s[j]>s[i]) cnt++; sum+=cnt*dir[i-1]; } return sum;}int ABS(int x) {return x<0?(-x):x;}int h(int s[])//不算x时的曼哈顿距离{ int curx,cury,endx,endy,sum,i,ans; sum=0; for(i=1;i<=9;i++) { if(s[i]==9) continue; ans=s[i]; curx=(i+2)/3; cury=(i-1)%3+1; endx=(ans+2)/3; endy=(ans-1)%3+1; sum=sum+ABS(curx-endx)+ABS(cury-endy); } return sum;}void bfs(){ int ans,i; priority_queue<node>q; node cur,next; cur.ans1=st=hash(a); visit[cur.ans1]=1; if(st==end) return; for(i=1;i<=9;i++) { cur.ma[i]=a[i]; if(a[i]==9) cur.x=i; } cur.g=0;//表示深度 cur.f=h(a); q.push(cur); while(!q.empty()) { cur=q.top(); q.pop(); if((cur.x+2)/3!=1) //向上翻 { next=cur; next.x=cur.x-3; next.ma[cur.x]=next.ma[next.x]; next.ma[next.x]=9; ans=hash(next.ma); if(!visit[ans]) { next.g++; next.f=next.g+h(next.ma); visit[ans]=1; next.ans1=ans; pre[ans]=cur.ans1; visit1[ans]='u'; if(ans==end) return; q.push(next); } } if((cur.x+2)/3!=3)//向下翻 { next=cur; next.x=cur.x+3; next.ma[cur.x]=next.ma[next.x]; next.ma[next.x]=9; ans=hash(next.ma); if(!visit[ans]) { next.g++; next.f=next.g+h(next.ma); visit[ans]=1; next.ans1=ans; pre[ans]=cur.ans1; visit1[ans]='d'; if(ans==end) return; q.push(next); } } if(cur.x%3!=1)//向左翻 { next=cur; next.x=cur.x-1; next.ma[cur.x]=next.ma[next.x]; next.ma[next.x]=9; ans=hash(next.ma); if(!visit[ans]) { next.g++; next.f=next.g+h(next.ma); visit[ans]=1; next.ans1=ans; pre[ans]=cur.ans1; visit1[ans]='l'; if(ans==end) return; q.push(next); } } if(cur.x%3!=0)//向右翻 { next=cur; next.x=cur.x+1; next.ma[cur.x]=next.ma[next.x]; next.ma[next.x]=9; ans=hash(next.ma); if(!visit[ans]) { next.g++; next.f=next.g+h(next.ma); visit[ans]=1; next.ans1=ans; pre[ans]=cur.ans1; visit1[ans]='r'; if(ans==end) return; q.push(next); } } }}int check(int s[]){ int i,j,cnt=0; for(i=1;i<=9;i++) { if(s[i]==9) continue; for(j=1;j<i;j++) { if(s[j]==9) continue; if(s[j]>s[i]) cnt++; } } return cnt;}int main(){ int i,j,ans; char str[50]; while(gets(str)) { ans=0; memset(visit,0,sizeof(visit)); for(i=0;str[i];i++) if(str[i]=='x') a[++ans]=9; else if(str[i]!=' ') a[++ans]=str[i]-'0'; end=0; ans=check(a); if(ans%2) {puts("unsolvable");continue;} bfs(); j=0; while(end!=st) { str[j++]=visit1[end]; end=pre[end]; } for(i=j-1;i>=0;i--) printf("%c",str[i]); puts(""); } return 0;}
转自:http://www.cnblogs.com/183zyz/archive/2011/08/12/2135827.html
- HDU 1043
- Hdu 1043
- HDU 1043
- HDU-1043
- hdu 1043
- HDU 1043 八数码
- hdu 1043 Eight
- HDU 1043 Eight
- HDU 1043、POJ 1077
- 周赛 HDU 1043 Eight
- Hdu 1043 Eight
- hdu 1043 BFS
- hdu 1043 A*
- HDU 1043 Eight
- HDU 1043 Eight
- HDU 1043 Eight
- HDU 1043 Eight
- hdu 1043 Eight
- 开启线程
- android Touch事件传递自己理解
- 相机闪存卡数据恢复方法/数码相机误删照片恢复详解
- POJ 3566
- No.10 Xcode(5.1.x) UITabBarController
- Hdu 1043
- POJ 1009 Edge Detection(模拟)
- 如何使用KeyChain保存和获取UDID
- Digital Roots——ZOJ 1115
- vc6.0与vs2010库文件添加
- C语言的本质(23)——C标准库之输入与输出(上)
- dfadfafa
- 批处理中set截取字符详解
- 数据挖掘笔记-特征选择-信息增益