UVALive 6665 Dragonâs Cruller(BFS+优先队列+康拓展开)
来源:互联网 发布:手机游戏挂机软件 编辑:程序博客网 时间:2024/05/16 18:30
题目链接:
UVALIve 6665 Dragonas Cruller
题意:
以九宫格的形式给出0–8八个数字,然后通过移动0数字,使这个九宫格变成给定的状态,上下移动和左右移动的权值不一样,求最小移动路径值。
分析:
用康拓排序来去重。
因为上下移动和左右移动的权值不一样,所以必须使用优先队列,这样才能保证解的优先性。
然而3000MS的限制还是跑了2979MS,好险。。。。。。o(╯□╰)o
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <queue>#include <set>#include <string>using namespace std;const int maxn=400000;int ch,cv,ans,st,ed,pos,npos;int ast[15],aed[15],temp[15],fac[15]={1,1};int vis[maxn];struct Node{ int cost,pos,cantor; //当前状态下的路径值,0位置和康拓值 bool operator < (const Node& a) const { return cost>a.cost; }}cur,nextnode;void CalcFac(){ for(int i=2;i<10;i++){ fac[i]=fac[i-1]*i;//计算阶乘 //printf("fac[%d]=%d\n",i,fac[i]); }}int AToInt(int a[])//数组状态装换成相应康拓值{ int x=0; for(int i=0;i<9;i++){ int y=a[i]; for(int j=0;j<i;j++){//去掉已经用过的比a[i]小的值 if(a[j]<a[i]) y--; } x+=fac[8-i]*y;//从右往左看是第8-i位 } return x;}void IntToA(int x,int *a)//康拓值转换成数组{ int vvis[10]; memset(vvis,0,sizeof(vvis)); for(int i=0;i<9;i++){ int y=x/fac[8-i];//第8-i位应该是第y小的数字 for(int j=0;j<9;j++){ if(!vvis[j]){//没被用过的数字 if(y==0){//这时j就是没被用过的第y大的数字 vvis[j]=1,a[i]=j; break; } y--; } } x%=fac[8-i]; }}void change(int i,int flag){//需要在每次i之后将temp数组还原,如果是每次i都重新调用IntToA来计算temp会TLE if(flag==1){ if(i==0){ npos=(pos+3)%9;//向下移动 swap(temp[pos],temp[npos]); } else if(i==1){ npos=(pos+6)%9;//向上移动 swap(temp[pos],temp[npos]); } else if(i==2){ npos=(pos+8)%9;//向左移动 swap(temp[pos],temp[npos]); } else if(i==3){//向右移动 npos=(pos+1)%9; swap(temp[pos],temp[npos]); } } else swap(temp[pos],temp[npos]);//还原temp}int bfs(){ int x; priority_queue<Node> que; memset(vis,0,sizeof(vis)); cur.cost=0; cur.cantor=st; que.push(cur); vis[st]=1; int flag=0; while(!que.empty()) { cur=que.top(); que.pop(); //printf("cur.cantor=%d cur.cost=%d\n",cur.cantor,cur.cost); if(cur.cantor==ed) { x=cur.cost,flag=1; break; } //if(vis[cur.cantor]) continue; pos=cur.pos,npos; IntToA(cur.cantor,temp); for(int i=0;i<4;i++) { change(i,1); nextnode.cost=cur.cost+((i<2)?cv:ch); /* printf("i=%d pos=%d npos=%d cost=%d\n",i,pos,npos,nextnode.cost); for(int j=0;j<9;j++) printf("%d",temp[j]); printf("\n"); */ nextnode.pos=npos; nextnode.cantor=AToInt(temp); /* if(nextnode.cantor==ed) { x=nextnode.cost,flag=1; break; } */ if(!vis[nextnode.cantor]||vis[nextnode.cantor]>nextnode.cost){ vis[nextnode.cantor]=nextnode.cost; que.push(nextnode); } change(i,0); } //if(flag) break; } return x;}int main(){#ifdef LOCAL freopen("in.txt","r",stdin);#endif CalcFac(); while(~scanf("%d%d",&ch,&cv)) { if(ch==0&&cv==0) break; for(int i=0;i<9;i++){ scanf("%d",&ast[i]); if(ast[i]==0) cur.pos=i; } for(int i=0;i<9;i++) scanf("%d",&aed[i]); st=AToInt(ast); ed=AToInt(aed); //printf("st=%d ed=%d\n",st,ed); ans=bfs(); printf("%d\n",ans); } return 0;}
给函数加inline,稍微快了点,2692MS。。。。。。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <queue>#include <set>#include <string>using namespace std;const int maxn=400000;int ch,cv,ans,st,ed,pos,npos;int ast[15],aed[15],temp[15],fac[15]={1,1};int vis[maxn];struct Node{ int cost,pos,cantor; bool operator < (const Node& a) const { return cost>a.cost; }}cur,nextnode;inline void CalcFac(){ for(int i=2;i<10;i++){ fac[i]=fac[i-1]*i; //printf("fac[%d]=%d\n",i,fac[i]); }}inline int ArrayToInt(int a[]){ int x=0; for(int i=0;i<9;i++){ int y=a[i]; for(int j=0;j<i;j++){ if(a[j]<a[i]) y--; } x+=fac[8-i]*y; } return x;}inline void IntToArray(int x,int *a){ int vvis[10]; memset(vvis,0,sizeof(vvis)); for(int i=0;i<9;i++){ int y=x/fac[8-i]; for(int j=0;j<9;j++){ if(!vvis[j]){ if(y==0){ vvis[j]=1,a[i]=j; break; } y--; } } x%=fac[8-i]; }}inline int bfs(){ int x; priority_queue<Node> que; memset(vis,0,sizeof(vis)); cur.cost=0; cur.cantor=st; que.push(cur); vis[st]=1; int flag=0; while(!que.empty()){ cur=que.top(); que.pop(); if(cur.cantor==ed){ x=cur.cost; break; } pos=cur.pos,npos; IntToArray(cur.cantor,temp); for(int i=0;i<4;i++){ if(i==0){ npos=(pos+3)%9; swap(temp[pos],temp[npos]); }else if(i==1){ npos=(pos+6)%9; swap(temp[pos],temp[npos]); }else if(i==2){ npos=(pos+8)%9; swap(temp[pos],temp[npos]); }else if(i==3){ npos=(pos+1)%9; swap(temp[pos],temp[npos]); } nextnode.cost=cur.cost+((i<2)?cv:ch); nextnode.pos=npos; nextnode.cantor=ArrayToInt(temp); if(!vis[nextnode.cantor]||vis[nextnode.cantor]>nextnode.cost){ vis[nextnode.cantor]=nextnode.cost; que.push(nextnode); } swap(temp[pos],temp[npos]); } } return x;}int main(){#ifdef LOCAL freopen("in.txt","r",stdin);#endif CalcFac(); while(~scanf("%d%d",&ch,&cv)){ if(ch==0&&cv==0) break; for(int i=0;i<9;i++){ scanf("%d",&ast[i]); if(ast[i]==0) cur.pos=i; } for(int i=0;i<9;i++) scanf("%d",&aed[i]); st=ArrayToInt(ast); ed=ArrayToInt(aed); ans=bfs(); printf("%d\n",ans); } return 0;}
0 0
- UVALive 6665 Dragonâs Cruller(BFS+优先队列+康拓展开)
- UVALive 6665 Dragon’s Cruller (BFS + 优先队列+hash)
- UVALive 6665 Dragonâs Cruller --BFS,类八数码问题
- LA 6665 —— Dragon’s Cruller(搜索,A*)
- UVALive 6669 (LA 6669) Dragon’s Cruller (康托展开 + 最短路)
- UVALive-6665-Dragons Cruller(BFS+Hash)
- UVALive 6665Dragonas Cruller
- 【UVALive】2147 - Push!!(bfs+dfs+优先队列)
- UVALive-6665-Dragons Cruller(Dij+Hash)
- UVALive 6485 Electric Car Rally (BFS,优先队列)
- hdu5040(bfs,优先队列)
- hdu1242(BFS+优先队列)
- hdu1242(bfs+优先队列)
- Rescue (BFS 优先队列)
- Rescue(优先队列+bfs)
- rescue(BFS+优先队列)
- UVALive - 3135 - Argus (优先队列!!)
- UVALive 3135 Argus(优先队列)
- Jquery动态绑定事件
- iOS面试题(二)
- 心情随笔20160314
- 【计算机视觉】Histogram of Oriented Gridients(HOG) 方向梯度直方图
- 优化内容收货
- UVALive 6665 Dragonâs Cruller(BFS+优先队列+康拓展开)
- num1 第一次
- 手动绑定数据到DatList并实现编辑,删除,取消···
- lintcode:Convert Sorted List to Balanced BST
- python通用序列学习笔记
- 对于返回局部指针变量的思考
- 设计模式之外观模式
- C++11多线程之std::mutex
- 不用加减乘除做加法