题目大意: 地图中的五种元素:0代表墙 1代表空地 2代表人的起点 3代表出口 4代表炸弹的重启器 炸弹只有6秒的时间,地图中的任何地方都可以走多遍,如果遇到4,那么炸弹的时间被重置为6,要求算出人到达出口的最短时间。 解题思路: BFS+优先队列,只是标志状态的时候应该开一个三维数组,第三维用来标志到达该点炸弹所剩的时间。数据量有点小,优先队列跟一般队列木有区别,优先队列都0ms过了。 代码:
#include
#include
const int MAX=25;
const int inf=0x7fffffff;
using namespace std;
typedef struct node
{
	int x,y,time,step;
	friend bool operator<(const struct node &n1,const struct node &n2)
	{
		return n1.step>n2.step;
	}
}N;
int n,m;
int Map[MAX][MAX];
bool visited[MAX][MAX][MAX];
int vst[MAX][MAX];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
void init()
{
	memset(visited,false,sizeof(visited));
	for(int i=0;iQ;
	N cur,pre;
	pre.x=sx;
	pre.y=sy;
	pre.time=6;
	pre.step=0;
	vst[pre.x][pre.y]=0;
	Q.push(pre);
	while(!Q.empty())
	{
		pre=Q.top();
		Q.pop();
		if(pre.x==ex && pre.y==ey)
		{	
			return pre.step;
		}
		for(int i=0;i<4;i++)
		{
			cur=pre;
			cur.x+=dir[i][0];
			cur.y+=dir[i][1];
			cur.time--;
			cur.step++;
			if(cur.x>=1 && cur.x<=n && cur.y>=1 && cur.y<=m 
				&& Map[cur.x][cur.y]!=0 && visited[cur.x][cur.y][cur.time]==false)
			{
				if(cur.time>0 && Map[cur.x][cur.y]==4 )
				{
					visited[cur.x][cur.y][cur.time]=true;
					cur.time=6;
					Q.push(cur);
					vst[cur.x][cur.y]=cur.step;
					//visited[cur.x][cur.y]=true;
				}
				else if(cur.time>0 )
				{
					visited[cur.x][cur.y][cur.time]=true;
					Q.push(cur);
					vst[cur.x][cur.y]=cur.step;
					//visited[cur.x][cur.y]=true;
				}
			}
		}
	}
	return -1;
}
int main(void)
{
	int cas;
	scanf("%d",&cas);
	while(cas--)
	{
		int sx,sy,ex,ey;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				scanf("%d",&Map[i][j]);
				if(Map[i][j]==2)
				{
					sx=i,sy=j;
					Map[i][j]=1;
				}
				if(Map[i][j]==3)
				{
					ex=i,ey=j;
					Map[i][j]=1;
				}
			}
		int ans=BFS(sx,sy,ex,ey);
		printf("%d\n",ans);
	}
	return 0;
}
posted on 2011-12-09 00:52  cchun  阅读(185)  评论(0编辑  收藏  举报