您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: