#include <iostream>
#include <stdio.h>
using namespace std;
/*
问题:设想有个机器人坐在X*Y网格的左上角,只能向右、向下移动。
假设有些点为“禁区”,机器人不能踏足。设计一种算法,找出一条路径,让机器人从左上角移动到右下角。
机器人从(0,0)到(X,Y)有多少种走法?
分析:题目的关键就是如何避免走到禁区,一种大的思路是:求出无禁区时的所有路径个数,减去以禁区为起点
到达终点的路径。这种方式需要考虑,如果存在多个禁区,两个禁区之间之间存在重复的路径,需要排除。
是否可以在递归中:直接令禁区对应的为0,即可
输入:
3(x) 3(y)
2(禁区个数n,下面有n行,每一行第一个数字是禁区的横坐标,第二个数字是禁区的纵坐标)
1(x坐标) 1(y坐标)
2 2
输出:
4
关键:
1 题目的关键就是如何避免走到禁区,可以在递归中:直接令禁区对应的路径个数为0,即可
2 //实例化一个二维数组,需要用二维指针和指针数组,int* [10]表示是一个指针数组,数组中每个元素是一个指针,指向含有10个元素的数组
int** pArr = new int* [y+1];
for(int i = 0 ; i <= x ; i++ )
{
pArr[i] = new int[y+1];
//初始化每个数组元素的值为-1
memset(pArr[i] , -1 , sizeof(pArr[i]) * (y+1));
}
*/
int countPaths(int** pArr , int x , int y)
{
if(NULL == pArr)
{
return -1;
}
if(x < 0 || y < 0)
{
return 0;
}
if( *(pArr[x] + y) != -1 )
{
return *(pArr[x] + y);
}
if( 0 == x)
{
return pArr[x][y] = 1;
}
if( 0 == y )
{
return pArr[x][y] = 1;
}
pArr[x][y] = countPaths(pArr ,x-1 ,y) + countPaths(pArr , x ,y-1);
return pArr[x][y];
}
void process()
{
int x , y;
int n;
int xIndex , yIndex;
while(cin >> x >> y)
{
if(x < 0 || y < 0)
{
cout << "x,y is false ,input again" << endl;
continue;
}
//实例化一个二维数组,需要用二维指针和指针数组,int* [10]表示是一个指针数组,数组中每个元素是一个指针,指向含有10个元素的数组
int** pArr = new int* [y+1];
for(int i = 0 ; i <= x ; i++ )
{
pArr[i] = new int[y+1];
//初始化每个数组元素的值为-1
memset(pArr[i] , -1 , sizeof(pArr[i]) * (y+1));
}
//设置从起点到禁区对应的路径个数为0
cin >> n;
for(int k = 0 ; k < n ; k++)
{
cin >> xIndex >> yIndex;
if(xIndex < 0 || yIndex < 0)
{
continue;
}
pArr[xIndex][yIndex] = 0;
}
//接下来开始计算
int result = countPaths(pArr , x , y);
cout << result << endl;
//释放空间
for(int i = 0 ; i <= x ; i++ )
{
delete[] pArr[i];
}
delete[] pArr;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
程序员面试金典: 9.9 递归和动态规划 9.2机器人走路的方式_避免禁区
最新推荐文章于 2023-03-09 19:08:58 发布