笨笨熊搬家交通篇


笨笨熊搬家交通篇

描述:

    森林里的苯苯熊要乔迁新喜,上次他已经将物品打包完成,并约了朋友来帮忙。接下来他要选定一个搬家的时间,想了很久,就决定在国庆节进行,因为国庆放假朋友们都有时间啦。但是在森林里,从他现在房子到新豪宅,所经之地有山有水,路途曲折,甚至有些道路是不通的。
    请你和他一起查看指定的地图,看看从笨笨熊现在的房子到新宅之间,道路是否是畅通的呢?
    地图是R行、C列的矩阵,矩阵的每一个格子刚好是一天的行程。
    矩阵由“B”、“-”、“#”、“H”四种字符成员组成,其中:
    B: 代表苯苯熊现在的房子;
    H: 代表笨笨熊新的豪宅;
    -: 代表可以通行的道路;
    #: 代表无法通过的障碍(高山、大河等);
    此外,森林里也有交通规则地:在任务位置,只能向“上、下、左、右”四个方向中的其中一个方向行走。

运行时间限制:

无限制

内存限制:

无限制

输入:

4  // R的数值
4  // C的数值,下面是地图。
--##---
B-----H
#---#--
-------

输出:

Y //代表道路可达

N //代表道路不通

样例输入:

1

5

-B-H#

样例输出:

Y


思路:递归。从笨笨熊现在的房子处开始,分别从上下左右四个方向进行递归搜索。在递归的时候,要注意不要像来的方向返回去找。如当前位置为(1,2),向上查找时,到(0,2)位置处,在对(0,2)进行查找时,就不要向下再次查找(1,2)位置,不然会形成死循环。这个问题在代码中由如下体现:

1 != iDir + i && 5 != iDir + i

这里特别说明下:

根据定义的方向数组,int iDirection[4][2] = {{0,-1}, {0, 1}, {-1, 0}, {1,0}};//方向, 左右上下
iDir是取二维数组中行的下标,所以,iDir= 0,表示向左;iDir=1,向右;iDir=2,向上;iDir=3,向下

iDir表示上一个搜索位置到当前搜索位置的方向,如当前为(1,2),如果上一个为(1,1),此时iDir=2,表示从(1,1)到(1,2)是向右搜索的。

i是对当前位置进行搜索的四个方向,也是iDirection[4][2]中一维的下标。接着刚才的例子,在对(1,2)进行搜索时,就不能回到(1,1),即 i 在遍历四个方向时,不能向左搜索,即不能等于 0, 所以 i+iDir != 1;

上下不能返回查找, 即i+ iDir != 5;(读者可自行分析)

PS:如果数组iDirection[4][2]中定义的方向顺序不一样,这里

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

//查找路径
//iRow:地图的总行数
//iCol:地图的总列数
// chInMap: 地图,以为数组形式输入
//iCur: 当前所在行
//iCurCol: 当前所在列
//iDir: 上个位置到当前位置的方向
//iIsFirst: 是否是第一次调用,如果是第一次调用,需要找到起点(即老房子所在行列)

int FindPath(int iRow, int iCol, char *chInMap, int iCurRow, int iCurCol, int iIsFirst, int iDir)
{
	if (iCurRow >= iRow || iCurCol >= iCol || iCurCol < 0 || iCurRow < 0)
	{
		return 0;
	}

	int iDirection[4][2] = {{0,-1}, {0, 1}, {-1, 0}, {1,0}};//方向, 左右上下
	
	int iIsBeak = 0;
	if(iIsFirst == 1)
	{
		int iRow_i, iCol_i;

		//找到老房子
		for (iRow_i = 0; iRow_i<iRow; iRow_i++)
		{
			for (iCol_i=0; iCol_i<iCol; iCol_i++)
			{
				if (chInMap[iRow_i * iCol + iCol_i] == 'B')
				{
					iIsBeak = 1;
					break;
				}
			}

			if (iIsBeak == 1)
			{
				break;
			}
		}
		
		iCurRow = iRow_i; 
		iCurCol = iCol_i;
	}

	int i=0;
	for (; i<4; i++)
	{
		//到达新居
		if (chInMap[(iCurRow + iDirection[i][0])* iCol + iCurCol + iDirection[i][1]] == 'H')
		{
			return 1;
		}//路可行,且不是当前的的来路
		if (chInMap[(iCurRow + iDirection[i][0]) * iCol + iCurCol + iDirection[i][1]] == '-'
			&& 1 != iDir + i && 5 != iDir + i)
		{
			if(1 == FindPath(iRow, iCol, chInMap, iCurRow + iDirection[i][0], iCurCol + iDirection[i][1], 0, i))
			{
				return 1;
			}
		}//换一个方向试探
		else
		{
			continue;
		}
	}
	
	return 0;
}

void main()
{
	int iRow = 0;
	int iCol = 0;

	scanf("%d", &iRow);
	scanf("%d", &iCol);

	char * pchTmp = (char *)(malloc)(sizeof(char) * (iCol + 1));
	char * pchMap = (char *)(malloc)(sizeof(char) * (iCol * iRow + 1));
	char * pchMapTmp = pchMap;

	if (NULL == pchTmp || NULL == pchMap)
	{
		return;
	}

	int i=0;
	for (; i<iRow; i++)
	{
		scanf("%s", pchTmp);
		memcpy(pchMapTmp, pchTmp, sizeof(char) * (iCol + 1));
		pchMapTmp += sizeof(char) * (iCol);
	}

	int iRst;
	iRst = FindPath(iRow, iCol, pchMap, 0, 0, 1, -5);
	if (iRst == 1)
	{
		printf("Y\n");
	}
	else
	{
		printf("N\n");
	}
}

是不同的。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值