一个计算路径条数的算法

题目如下:

 

有一个横3,竖4的格子,格子的左上顶点坐标为(0,0),右下顶点坐标为(3,2),在不弯路的情况下,求从(0,0)到(3,2)的路径条数。

 

一个算法如下:

 

令一个顶点用V表示,S(V)记为到该顶点的路径条数,那么S(V)=S(V1)+S(V2)+S(V3)+S(V4),其中V1,V2,V3,V4为V的相邻顶点。即:计算到达一个顶点的路径条数,可以分别计算到达该顶点相邻节点的路径的条数,则该顶点的路径条数记为相邻节点路径条数之和。

 

一个C实现的版本:

 

#include "stdlib.h";

#ifndef PATH_CAL
#define PATH_CAL

struct PointNode;
struct ResultNode;

typedef struct PointNode *Point;
typedef struct ResultNode *Result;

struct PointNode{
    int x;
    int y;
};

#define POINT_X 3
#define POINT_Y 2

#endif

int inDests(int x,int y,Point preDests[],int preNumber){
    int i=0;
    int result = 0;
    for(i=0; i<preNumber; ++i){
        // printf("(%d,%d)\n",preDests[i]->x,preDests[i]->y);
        if(preDests[i]->x==x && preDests[i]->y==y){
            result = 1;
            break;
        }
    }

    return result;
}


int calPath(int maxX,int maxY,Point dest,Point preDests[],int preNumber){
    int i;

    int a,b,c,d;

    Point *newDests1;
    Point *newDests2;
    Point *newDests3;
    Point *newDests4;

    Point newDest1 = NULL;
    Point newDest2 = NULL;
    Point newDest3 = NULL;
    Point newDest4 = NULL;

    int preNumber1 = 0;
    int preNumber2 = 0;
    int preNumber3 = 0;
    int preNumber4 = 0;

    if(dest==NULL)  return 0;
    if(dest->x>maxX || dest->x<0)    return 0;
    if(dest->y>maxY || dest->y<0) return 0;

    if(dest->x==0 && dest->y==0)    return 1;

    //printf("目标点:(%d,%d)\n",dest->x,dest->y);

    //找到dest的相邻节点
    if(dest->x-1<=maxX && dest->x-1>=0){
        //如果这个相邻节点不在之前的目标节点中,则计算该目标节点
        if(inDests(dest->x-1,dest->y,preDests,preNumber)==0){
            newDests1 = malloc((1+preNumber)*sizeof(Point));
            for(i=0; i<preNumber; ++i){
                newDests1[i] = preDests[i];
            }

            newDest1 = malloc(sizeof(struct PointNode));
            newDest1->x = dest->x-1;
            newDest1->y = dest->y;

            newDests1[i] = dest;
            preNumber1 = preNumber+1;
        }
    }

    if(dest->x+1<=maxX && dest->x+1>=0){
        //如果这个相邻节点不在之前的目标节点中,则计算该目标节点
        if(inDests(dest->x+1,dest->y,preDests,preNumber)==0){
            newDests2 = malloc((1+preNumber)*sizeof(Point));
            for(i=0; i<preNumber; ++i){
                newDests2[i] = preDests[i];
            }

            newDest2 = malloc(sizeof(struct PointNode));
            newDest2->x = dest->x+1;
            newDest2->y = dest->y;

            newDests2[i] = dest;

            preNumber2 = preNumber+1;

        }
    }

    if(dest->y-1<=maxY && dest->y-1>=0){
        //如果这个相邻节点不在之前的目标节点中,则计算该目标节点
        if(inDests(dest->x,dest->y-1,preDests,preNumber)==0){
            newDests3 = malloc((1+preNumber)*sizeof(Point));
            for(i=0; i<preNumber; ++i){

                newDests3[i] = preDests[i];
            }

            newDest3 = malloc(sizeof(struct PointNode));
            newDest3->x = dest->x;
            newDest3->y = dest->y-1;

            newDests3[i] = dest;

            preNumber3 = preNumber+1;

        }
    }

    if(dest->y+1<=maxY && dest->y+1>=0){
        //如果这个相邻节点不在之前的目标节点中,则计算该目标节点
        if(inDests(dest->x,dest->y+1,preDests,preNumber)==0){
            newDests4 = malloc((1+preNumber)*sizeof(Point));
            for(i=0; i<preNumber; ++i){
                newDests4[i] = preDests[i];
            }

            newDest4 = malloc(sizeof(struct PointNode));
            newDest4->x = dest->x;
            newDest4->y = dest->y+1;

            newDests4[i] = dest;

            preNumber4 = preNumber+1;
        }
    }

    a = calPath(maxX,maxY,newDest1,newDests1,preNumber1);
    b = calPath(maxX,maxY,newDest2,newDests2,preNumber2);
    c = calPath(maxX,maxY,newDest3,newDests3,preNumber3);
    d = calPath(maxX,maxY,newDest4,newDests4,preNumber4);

    return a+b+c+d;
}


int main(){
    int paths;

    Point point = malloc(sizeof(struct PointNode));
    point->x = POINT_X;
    point->y = POINT_Y;

    printf("计算中...\n");

    paths = calPath(POINT_X,POINT_Y,point,NULL,0);

    printf("路径条数:%d",paths);

    return 1;
}


 

 

最终的计算结果为:38。

 

这个实现很粗糙,空间浪费很大。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
弗洛伊德算法是一种用于解决图中最短路径问题的动态规划算法。它通过不断更新图中任意两个顶点之间的最短路径信息来找到所有顶点之间的最短路径。对于一个给定的图,弗洛伊德算法可以保证路径数不超过n条。 在弗洛伊德算法的每一次迭代中,通过遍历所有可能的顶点对,算法会不断更新顶点之间的最短距离和路径信息。具体地,算法会尝试将中间顶点纳入路径,看是否能够缩短路径长度。这样在每一次迭代中,算法都会更新路径信息,直到所有顶点对之间的最短路径都被求解出来。 在弗洛伊德算法中,通过使用一个二维数组来存储任意两个顶点之间的最短路径长度。尽管在每一次迭代中,会对每个顶点对进行一次遍历,但通过合理的计算和更新策略,算法可以避免重复计算,并且保证最终得到的结果是最短路径。 而对于路径数不超过n条的保证,这是由于算法的特性决定的。在每一次迭代中,算法都会检查所有可能的路径,并尝试更新路径信息。假设图中存在n个顶点,那么每个顶点对之间的路径数最多有n条(即通过相邻顶点的直接路径)。而在迭代过程中,算法已经考虑了所有可能的路径,并进行了相应的更新。因此,弗洛伊德算法可以保证路径数不超过n条。 总而言之,弗洛伊德算法通过动态规划的方式,通过不断更新图中顶点之间的最短路径信息来找到所有顶点之间的最短路径。由于算法内部的计算和更新策略,弗洛伊德算法可以保证路径数不超过n条。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值