hdu 1026

题目大意:输入迷宫的行列n,m,问怎么走使得从(0,0)到((n-1),(m-1))所用时间最短,输出相应格式。

从终点开始往回走,对于用时最少的每一个点,入队,并且记录前驱。直到(0,0),从起点还是输出,下个点为起点的前驱点,直到终点。

#include <stdio.h>
#include <string.h>

#define MAX 100000

typedef struct
{
	int x,y;
	int front;//记录这个节点的前驱节点
	int time;
}Node;
Node node[1000000]; //构造队列
int n,m,low,up;
int min[110][110];
char f[110][110];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};

void BFS()
{
	int i;
	Node temp,next;

	while(low!=up)
	{
		temp=node[low++];
		for(i=0;i<4;i++)
		{
			next.x=temp.x+dir[i][0];
			next.y=temp.y+dir[i][1];
			if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&f[next.x][next.y]!='X')
			{
				next.time=temp.time+1;
				if(f[next.x][next.y]!='.')
					next.time+=f[next.x][next.y]-'0';
				if(next.time<min[next.x][next.y])
				{
					next.front=low-1;
					min[next.x][next.y]=next.time;
					node[up++]=next;
				}
			}
		}
	}
}

int main()
{
	int time,i,j,next;
	Node temp;

	while(scanf("%d %d",&n,&m)!=EOF)
	{
		getchar();
		memset(min,0,sizeof(min));
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				scanf("%c",&f[i][j]);
				min[i][j]=MAX;
			}
			getchar();
		}
		node[0].x=n-1;//初始化
		node[0].y=m-1;
		node[0].front=-1;
		node[0].time=0;
		min[n-1][m-1]=0;
		if(f[n-1][m-1]>='1'&&f[n-1][m-1]<='9')
			node[0].time+=f[n-1][m-1]-'0';
		low=0,up=1;
		BFS();
		if(min[0][0]==MAX)
			printf("God please help our poor hero.\n");
		else
		{
			printf("It takes %d seconds to reach the target position, let me show you the way.\n",min[0][0]);
			temp=node[low-1];
			while(temp.x!=0||temp.y!=0)
			{
				temp=node[--low];
			}
			time=1;
			while(temp.front>=0)//寻找前驱
			{
				next=temp.front;
				printf("%ds:(%d,%d)->(%d,%d)\n",time++,temp.x,temp.y,node[next].x,node[next].y);
				if(f[node[next].x][node[next].y]>='1'&&f[node[next].x][node[next].y]<='9')
				{
					for(i=0;i<f[node[next].x][node[next].y]-'0';i++)
					{
						printf("%ds:FIGHT AT (%d,%d)\n",time++,node[next].x,node[next].y);
					}
				}
				temp=node[next];
			}
		}
		printf("FINISH\n");
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值