现在的位置: 首页 > 综合 > 正文

解题报告-HDOJ-1242(广度优先搜索)

2013年08月13日 ⁄ 综合 ⁄ 共 1966字 ⁄ 字号 评论关闭

题意:

在一个N*M的地图中拯救出一个被困在迷宫中的天使,地图中的“.”表示道路,“a”表示被困的天使,“r”表示天使的朋友,“x”表示守卫,“#”表示围墙(“x”和“#”貌似在题目中没有描述出来,以至于笔者纠结了很长时间)。

假设拯救出天使相当于天使的朋友跑到天使所在的位置,每移动一格,需要消耗一个单位的时间,如果道路上有士兵则需要先把士兵消灭,消灭士兵需要一个单位的时间。输出找到天使所需要的最小时间。如果不能找到天使,则输出“Poor ANGEL has to stay in the prison all his life.”。

解决这道题目的思路是广搜,广搜的思想就不多说了,我们直接说这道题目。我将用一个结构体来描述每一个位置。结构体中的x用来保存该点的信息,如果是围墙就用-1表示,如果是士兵就用2表示(因为经过有士兵的地方需要消耗2个单位的时间),如果是道路就用1表示(知消耗1个单位的时间),如果是天使就用0表示,如果是天使的朋友就用-3表示。

在计算过程中,由于题目没有给出天使的朋友有多少个,所以我们选择从天使开始进行广搜,直到找到了天使的朋友。在搜索的同时记录天使到该点所需要的时间,用结构体中的step记录,step是由经过该点的时间x(这就是为什么将士兵用2保存,道路用1保存)加上前一个点的step得到的,而前一个点就是队头。

以下就是我自己写的AC代码:(我看到有些大牛的代码是0MS的,我这个花了31MS,大家发现有什么可以改进的都可以讨论一下,这是我第一次写的解题报告,希望大家能给我一些新想法,新意见。)

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

typedef struct node{
	int x;//保存位置信息
	int i,j;
	int step;
}node;

const int MAXN = 200 + 10;
node map[MAXN][MAXN];
int used[MAXN][MAXN];
int col[4][2] = {1,0,0,1,-1,0,0,-1};//方向向量

int main()
{
	int n,m;
	while(cin>>n>>m)
	{
		queue <node> Q;
		memset(used,0,sizeof(used));
		memset(map,-1,sizeof(map));
		int i,j;
		char x[MAXN];
		int angle_x,angle_y;
		for (i = 0; i < n; i++)
		{
			scanf("%s",x);
			for (j = 0; j < m; j++)
			{
				map[i][j].step = 0;
				map[i][j].i = i;
				map[i][j].j = j;
				if (x[j] == '#')
				{
					map[i][j].x = -1;
				}
				else if (x[j] == 'x')
				{
					map[i][j].x = 2;
				}
				else if (x[j] == '.')
				{
					map[i][j].x = 1;
				}
				else if (x[j] == 'a')
				{
					map[i][j].x = 0;
					angle_x = i;
					angle_y = j;
				}
				else if (x[j] == 'r')
				{
					map[i][j].x = -3;
				}
			}
		}
		Q.push(map[angle_x][angle_y]);
		used[angle_x][angle_y] = 1;
		int flag = 0;
		while (!Q.empty())
		{
			node N = Q.front();
			for (int k = 0; k < 4; k++)
			{
				if (N.i + col[k][0] >= 0 && N.i + col[k][0] < n && N.j + col[k][1] >= 0 && N.j + col[k][1] < m)//判断是否越界
				{
					if (map[N.i + col[k][0]][N.j + col[k][1]].x > 0 && used[N.i + col[k][0]][N.j + col[k][1]] == 0)//该点是否能通过且是否被标记
					{
						map[N.i + col[k][0]][N.j + col[k][1]].step = map[N.i + col[k][0]][N.j + col[k][1]].x + Q.front().step;
						used[N.i + col[k][0]][N.j + col[k][1]] = 1;
						Q.push(map[N.i + col[k][0]][N.j + col[k][1]]);
					}
					else if (map[N.i + col[k][0]][N.j + col[k][1]].x == -3)
					{
						flag = map[N.i][N.j].step + 1;
						break;
					}
				}
			}
			Q.pop();
			if (flag)
			{
				break;
			}
		}

		if (flag)
		{
			cout<<flag<<endl;
		}
		else 
		{
			cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
		}
	}
	return 0;
}

抱歉!评论已关闭.