您的位置:首页 > 其它

ZOJ 3652 Maze 优先队列 模拟

2012-09-30 01:32 405 查看
题意:有n*m(1 <= n m <= 50)的格子,-1代表不能走的地方,0代表空地,整数k(1<=k<=5)代表当前格子被k号怪物控制,但是每个怪物不一定在自己

控制的范围内,一个人从给定的源点走到终点,每回合能走l移动值(1<=l<=10)块空地(如果k号怪物被打死了那么k号怪物控制的范围视为空地),

如果走到一个编号问k且k号怪物还没死的空地,那么移动值立刻减为0,问最少要几个回合能走到终点。

题解:比赛的时候已经想到了四维记录状态[i][j][k][l]表示到达i j 位置打死怪物的状态为 k 剩余步数为 l 的最小回合数,但是更新时候的一个状态被我搞没了,

一直在wa,比赛之后也wa了好久,还是自己的模拟功力不够吧唉,伤心……

Sure原创,转载请注明出处。

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <queue>
using namespace std;
const int inf = 1 << 29;
const int maxn = 52;
const int maxk = 7;
const int maxl = 12;
const int move[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
struct ddd
{
int x,y;
int st,le;
int turn;
bool operator < (const ddd &other) const
{
if(turn == other.turn)
{
return le < other.le;
}
return turn > other.turn;
}
};
int mon[maxn][maxn],map[maxn][maxn];
bool vis[maxn][maxn][1 << maxk][maxl];
priority_queue <ddd> Q;
int k,m,n,l,sx,sy,ex,ey;

void read()
{
memset(vis,false,sizeof(vis));
memset(mon,0,sizeof(mon));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
}
}
scanf("%d",&k);
int x,y;
for(int i=1;i<=k;i++)
{
scanf("%d %d",&x,&y);
mon[x][y] = i;
}
scanf("%d %d %d %d",&sx,&sy,&ex,&ey);
return;
}

bool judge(int x,int y)
{
if(x >= 1 && y >= 1 && x <= m && y <= n && map[x][y] != -1)
{
return true;
}
return false;
}

void bfs()
{
if(sx == ex && sy == ey)   //源点和终点重合
{
puts("0");
return;
}
int res = -1;
while(!Q.empty()) Q.pop();
ddd cur,tmp;
tmp.x = sx;
tmp.y = sy;
tmp.st = 0;
tmp.le = 0;
tmp.turn = 0;
vis[sx][sy][0][0] = true;
Q.push(tmp);  //加入起始状态
while(!Q.empty())
{
cur = Q.top();
Q.pop();
if(cur.x == ex && cur.y == ey)
{
res = cur.turn;
break;
}
if(cur.le == 0)  //开始时我把到达每个点剩余步数为0的状态扔掉了……
{
cur.turn++;
cur.le = l;
if(vis[cur.x][cur.y][cur.st][cur.le] == false)
{
vis[cur.x][cur.y][cur.st][cur.le] = true;
Q.push(cur);
}
continue;
}
for(int i=0;i<4;i++)
{
int xx = cur.x + move[i][0];
int yy = cur.y + move[i][1];
if(judge(xx , yy))
{
int ss,tt,ll;
if(map[xx][yy] == 0 || cur.st & (1 << (map[xx][yy] - 1)))
{
ss = cur.st;
if(mon[xx][yy])
{
ss |= (1 << (mon[xx][yy] - 1));
}
tt = cur.turn;
ll = cur.le - 1;
}
else
{
if(mon[xx][yy] == 0)
{
ss = cur.st;
tt = cur.turn;
ll = 0;
}
else
{
ss = cur.st | (1 << (mon[xx][yy] - 1));
tt = cur.turn;
ll = 0;
}
}
if(vis[xx][yy][ss][ll] == false)
{
vis[xx][yy][ss][ll] = true;
tmp.x = xx;
tmp.y = yy;
tmp.st = ss;
tmp.turn = tt;
tmp.le = ll;
Q.push(tmp);
}
}
}
}
if(res == -1) puts("We need God's help!");
else printf("%d\n",res);
return;
}

int main()
{
while(~scanf("%d %d %d",&m,&n,&l))
{
read();
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: