POJ 1324 Holedox Moving 位运算+BFS
2015-08-02 20:47
351 查看
POJ 1324 Holedox Moving
题目描述:
题目链接:POJ 1324 Holedox Moving题目大意:
给定贪吃蛇的初始位置和洞穴中的石头的位置,问这个贪吃蛇到达洞口的最短时间。如果不能到达输出−1-1。解题思路:
这个题的难点在于对贪吃蛇状态的记录以及对蛇的状态的判重。由题知蛇长最大为7因此,我们可以用一个整数(int)的二进制来表示蛇的形态。每一格相对于其上一格的方向有四种即上下左右,我们可以分别用 00、01、10、1100、01、10、11 来表示。通过位运算的方式将其置于int的前14位。因此只要开一个最大为vis[22][22][1<<15]vis[22][22][1 << 15]的数组即可。然后进行bfs搜索。复杂度分析:
时间复杂度 :O(n∗m∗l)O(n*m*l)空间复杂度 :O(n∗m∗l)O(n*m*l)
AC代码:
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cstdio> using namespace std; struct state{ int x[10],y[10]; }s; struct node{ int x,y,s,k; }; int n,m,l,k; int vis[22][22][1<<15]; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int gm[22][22]; state decode(int x, int y, int s, int l){ int dire; state pos; pos.x[0] = x; pos.y[0] = y; for(int i = 1; i < l; i++){ dire = 3; dire &= s; s >>= 2; pos.x[i] = pos.x[i-1]+dir[dire][0]; pos.y[i] = pos.y[i-1]+dir[dire][1]; } return pos; } int encode(state s, int l){ int st = 0; for(int i = l - 1; i > 0; i--){ int x,y,now; x = s.x[i] - s.x[i-1]; y = s.y[i] - s.y[i-1]; if(x == 1 && y == 0) now = 0; else if(x == -1 && y == 0) now = 1; else if(x == 0 && y == 1) now = 2; else if(x == 0 && y == -1) now = 3; st <<= 2; st |= now; } return st; } node moves(node s, int d, int l){ int mod = (1 << ((l - 1) * 2)) - 1; int now; int nx,ny,x,y; nx = s.x + dir[d][0]; ny = s.y + dir[d][1]; x = -dir[d][0]; y = -dir[d][1]; if(x == 1 && y == 0) now = 0; else if(x == -1 && y == 0) now = 1; else if(x == 0 && y == 1) now = 2; else if(x == 0 && y == -1) now = 3; s.s <<= 2; s.s |= now; s.s &= mod; s.x = nx; s.y = ny; return s; } bool judge(int x, int y, int s, node pre){ if(x < 1 || x > n || y < 1 || y > m) return false; //越界检查 if(vis[x][y][s] == 1) return false; //移动之后自己还占着那个地方 if(gm[x][y] == 1) return false; //路被占 state sx = decode(pre.x, pre.y, pre.s,l); for(int i = 0; i < l; i++) if(sx.x[i] == x && sx.y[i] == y) return false; return true; } int bfs() { queue<node> q; node a, tp; a.x = s.x[0],a.y = s.y[0]; a.s = encode(s,l); a.k = 0; q.push(a); vis[a.x][a.y][a.s] = 1; while(!q.empty()) { a = q.front(); q.pop(); if(a.x == 1 && a.y == 1) return a.k; for(int i=0;i<4;i++) { tp = moves(a,i,l); tp.k = a.k+1; if(!judge(tp.x,tp.y,tp.s,a)) continue; vis[tp.x][tp.y][tp.s] = 1; q.push(tp); } } return -1; } int main(){ int kase = 0; while(scanf("%d%d%d",&n,&m,&l) == 3){ if(!(n||m||l))return 0; memset(vis,false,sizeof(vis)); memset(gm,0,sizeof(gm)); for(int i = 0; i < l;i++){ scanf("%d%d",&s.x[i],&s.y[i]); } int x,y; scanf("%d",&k); for(int i = 0; i < k;i++){ scanf("%d%d",&x,&y); gm[x][y] = 1; } printf("Case %d: %d\n",++kase,bfs()); } return 0; }
相关文章推荐
- Python学习之异常
- 20150802-网络连接-TCP
- C语言:通过指针函数输出二维数组中每个学生的成绩
- C# NamePipe使用小结
- Program A - 暴力求解
- POJ 2393 贪心 简单题
- 爬虫Spider
- HDFS文件操作
- HDU OJ Dividing 题目1059
- Python学习之函数
- 每天一个小知识点21(拖拽效果)
- Asp.net-知识总结(2)
- 【DB.MySQL】在Mac如何启动MySQL
- 虚幻3引擎-多线程渲染机制
- scrapy学习笔记--解析结果存储
- 调用startActivityForResult后onActivityResult立刻响应,返回当前页onActivityResult不响应的问题
- kiki's game
- 我多希望我学编程时,有人教我这些事!
- 拉格朗日乘数法
- 如何高性能布局