题目如下:
有一个横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。
这个实现很粗糙,空间浪费很大。