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

HDU1026——Ignatius and the Princess I(BFS)

2017年10月17日 ⁄ 综合 ⁄ 共 2150字 ⁄ 字号 评论关闭

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026

典型的广度优先搜索,其实这个我已经写了很多遍了,但是写这个代码的时候还是花了我一上午的时间,为什么呢,以为我写代码的时候把中间最优值更新的部分的map[nx][ny]敲成了map[x][y],血淋淋的教训啊,尼玛,很熟练的写完了,调试了很久都觉得没错了。唉,所以说还有要细心一点啊。这种输入错误,很难找的。唉!不说了,说多了全是泪啊。其实这里可以用循环链表,这样比较节约空间,不过,鉴于现在没时间,先这样了呗~~

代码:

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

#define M 105

char map[M][M];
int used[M][M];
int dp[M][M];
int queue[2][5*M*M];
int stack[2][M*M];
int derect[2][4] = {{0,1,0,-1},{1,0,-1,0}};//右,下,左,上

void BFS(int n, int m)//n行m列
{
	int head,tail;
	int i,x,y;
	int nx,ny;
	queue[0][0] = 0;
	queue[0][0] = 0;
	head = 0;
	tail = 1;
	dp[0][0] = 0;
	used[0][0] = 0;
	while(head < tail)
	{
		x = queue[0][head];
		y = queue[1][head];
		for(i = 0; i < 4; ++i)
		{
			nx = x + derect[0][i];
			ny = y + derect[1][i];
			if(nx < 0 || nx >= n || ny < 0 || ny >= m)
				continue;
			if(used[nx][ny] < 0)//如果还没有标记过
			{
				used[nx][ny] = (i + 2)%4;//求反方向
				dp[nx][ny] += dp[x][y];
				queue[0][tail] = nx;
				queue[1][tail++] = ny;
			}
			else if(map[nx][ny] != 'X')//标记过之后,更新到这一点最短距离
			{
				if(map[nx][ny] == '.' && dp[x][y] + 1 < dp[nx][ny])
				{
					dp[nx][ny] = dp[x][y] + 1;
					used[nx][ny] = (i + 2) % 4;
					queue[0][tail] = nx;//最短路得到更新过后的数据要再次进队列,以便更新其后续的点
					queue[1][tail++] = ny;
				}
				else if( map[nx][ny] != '.' && map[nx][ny] - '0' + dp[x][y] + 1 < dp[nx][ny])
				{
					dp[nx][ny] = map[nx][ny] - '0' + dp[x][y] + 1;
					used[nx][ny] = (i + 2) % 4;
					queue[0][tail] = nx;//最短路得到更新过后的数据要再次进队列,以便更新其后续的点
					queue[1][tail++] = ny;
				}
			}
		}//for(i = 0; i < 4; ++i)
		++head;
	}//end while(head < tail)
}

void GetPath(int n, int m)
{
	int x,y;
	int temp;
	int top = 0;

	x = n - 1;
	y = m - 1;
	while(x || y)
	{
		stack[0][top] = x;
		stack[1][top] = y;
		temp = used[x][y];
		x += derect[0][temp];
		y += derect[1][temp];
		++top;
	}

	stack[0][top] = 0;
	stack[1][top] = 0;

	top = top - 1;
	temp = 1;
	while(top >= 0)
	{
		x = stack[0][top];
		y = stack[1][top];

		printf("%ds:(%d,%d)->(%d,%d)\n",temp++,stack[0][top+1],stack[1][top+1],x,y);
		for( ; temp <= dp[x][y]; ++temp)//如果在某一点有停留,打印fight
		{
			printf("%ds:FIGHT AT (%d,%d)\n",temp,x,y);
		}
		--top;
	}
}

void main()
{
	int n,m;
	int i,j;

	while(scanf("%d %d",&n,&m) != EOF)
	{
		getchar();
		memset(dp,0,sizeof(dp));

		for(i = 0; i < n; ++i)
		{
			for(j = 0; j < m; ++j)
			{
				used[i][j] = -1;
				scanf("%c",&map[i][j]);
				if(map[i][j] == 'X')
				{
					used[i][j] = 5;
				}
				else if(map[i][j]  == '.')
				{
					dp[i][j] = 1;
				}
				else
				{
					dp[i][j] = map[i][j] -'0' + 1;
				}
			}
			getchar();
		}

		BFS(n,m);
		if(used[n-1][m-1] < 0)
		{
			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",dp[n-1][m-1]);
			GetPath(n,m);
		}
		printf("FINISH\n");
	}
}

抱歉!评论已关闭.