OJ题-营救公主

题目描述如下:

题面:
500年前,Jesse是我国最卓越的剑客。他英俊潇洒,而且机智过人^_^。
突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中。Jesse听说这个消息已经是两天以后了,他知道公主在迷宫中还能坚持T天,他急忙赶到迷宫,开始到处寻找公主的下落。
时间一点一点的过去,Jesse还是无法找到公主。最后当他找到公主的时候,美丽的公主已经死了。从此Jesse郁郁寡欢,茶饭不思,一年后追随公主而去了。T_T
500年后的今天,Jesse托梦给你,希望你帮他判断一下当年他是否有机会在给定的时间内找到公主。

他会为你提供迷宫的地图以及所剩的时间T。请你判断他是否能救出心爱的公主。

Input
题目包括多组测试数据。
每组测试数据以三个整数N,M,T(0 < N,M <= 20)开头,
分别代表迷宫的长和高,以及公主能坚持的天数。
紧接着有M行,N列字符,由”.”,”*”,”P”,”S”组成。其中
“.” 代表能够行走的空地。
“*” 代表墙壁,Jesse不能从此通过。
“P” 是公主所在的位置。
“S” 是Jesse的起始位置。
每个时间段里Jesse只能选择“上、下、左、右”任意一方向走一步。
输入以0 0 0结束。

Output
如果能在规定时间内救出公主输出“YES”,否则输出“NO”。

Sample Input
4 4 10
....
....
....
S**P

Sample Output
YES

求解思路:采用广度优先搜索算法

代码如下:

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 20
typedef struct {
	int x;
	int y;
	int time;
}st_pos;

static int dir[][2] = { { 0, 1 }, { 1, 0 }, { -1, 0 }, { 0, -1 } };

/*
	广度优先搜索,用一个固定长度的数组实现队列的功能
*/
static int bfs(char *visited, st_pos start_pos, st_pos end_pos, int n, int m)
{
	int i = 0;
	int queue_length = 0;
	int queue_point_pos = 0;
	st_pos temp1_pos;
	st_pos temp2_pos;

	st_pos queue_pos[MAXSIZE * MAXSIZE];

	memset(&temp1_pos, 0, sizeof(st_pos));
	memset(&temp2_pos, 0, sizeof(st_pos));
	memset(queue_pos, 0, MAXSIZE * MAXSIZE *sizeof(st_pos));

	//加入队列
	queue_pos[0].x = start_pos.x;
	queue_pos[0].y = start_pos.y;
	queue_length++;
	while (queue_point_pos < queue_length)
	{
		//出队
		temp1_pos.x = queue_pos[queue_point_pos].x;
		temp1_pos.y = queue_pos[queue_point_pos].y;
		temp1_pos.time = queue_pos[queue_point_pos].time;
		queue_point_pos++;
		if (temp1_pos.x == end_pos.x && temp1_pos.y == end_pos.y)
			return temp1_pos.time;

		for (i = 0; i < 4; i++)
		{
			temp2_pos.x = temp1_pos.x + dir[i][0];
			temp2_pos.y = temp1_pos.y + dir[i][1];
			temp2_pos.time = temp1_pos.time;

			if (temp2_pos.x >= 0 && temp2_pos.x < m && temp2_pos.y >= 0 && temp2_pos.y < n
				&& visited[temp2_pos.x * n + temp2_pos.y] != '*'
				&& visited[temp2_pos.x * n + temp2_pos.y] != 'S')
			{
				visited[temp2_pos.x * n + temp2_pos.y] = '*';
				temp2_pos.time++;
				queue_pos[queue_length].x = temp2_pos.x;
				queue_pos[queue_length].y = temp2_pos.y;
				queue_pos[queue_length].time = temp2_pos.time;
				queue_length++;
			}

		}

	}
	return -1;
}
int _tmain(int argc, _TCHAR* argv[])
{
	char map[4][4] = { { '.', '.', '.', '.' }, { '.', '.', '.', '.' }, { '.', '.', '.', '.' }, { 'S', '*', '*', 'P' } };
	int m = 4;
	int n = 4;
	int t = 10;
	char *p = &map[0][0];
	st_pos start_pos;
	st_pos end_pos;
	int i = 0;
	int j = 0;
	memset(&start_pos, 0, sizeof(st_pos));
	memset(&end_pos, 0, sizeof(st_pos));

	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{
			if (map[i][j] == 'S')
			{
				start_pos.x = i;
				start_pos.y = j;
			}
			if (map[i][j] == 'P')
			{
				end_pos.x = i;
				end_pos.y = j;
			}
				
		}
	}
	printf("(%d,%d)-->(%d,%d)\n", start_pos.x, start_pos.y, end_pos.x, end_pos.y);
	int ret = bfs(p, start_pos, end_pos, n, m);
	printf("%d\n", ret);
	if (ret == -1 || ret > t)
		printf("NO");
	else
		printf("yes");
	system("pause");
	return 0;
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
杭州电子科技大学在线评测系统(杭电OJ)中的目1000-1100是一系列编程,我将分别进行回答。 1000是一个简单的入门,要求计算两个整数的和。我们可以使用一个简单的算法,读取输入的两个整数,然后将它们相加,最后输出结果即可。 1001是一个稍微复杂一些的目,要求实现字符串的逆序输出。我们可以使用一个循环来逐个读取输入的字符,然后将这些字符存储在一个数组中。最后,我们可以倒序遍历数组并将字符依次输出,实现字符串的逆序输出。 1002是一个求最大公约数的问。我们可以使用辗转相除法来解决,即先求出两个数的余数,然后将被除数更新为除数,将除数更新为余数,直至两个数的余数为0。最后的被除数就是最大公约数。 1003是一个比较简单的排序问。我们可以使用冒泡排序算法来解决,即每次比较相邻的两个元素,如果它们的顺序错误就交换它们的位置。重复这个过程直至整个数组有序。 1100是一个动态规划问,要求计算给定序列中的最长上升子序列的长度。我们可以使用一个数组dp来保存到达每个位置的最长上升子序列的长度。每当遍历到一个位置时,我们可以将其和之前的位置比较,如果比之前位置的值大,则将其更新为之前位置的值加1,最后返回dp数组的最大值即可。 以上是对杭电OJ1000-1100目的简要回答,涉及了一些基本的编程知识和算法思想。希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值