[Project Euler] 来做欧拉项目练习题吧: 题目015

时间:2023-02-22 23:35:37

                                       [Project Euler] 来做欧拉项目练习题吧: 题目015

                                                    周银辉

 

问题描述

Starting in the top left corner of a 2[Project Euler] 来做欧拉项目练习题吧: 题目0152 grid, there are 6 routes (without backtracking) to the bottom right corner.

[Project Euler] 来做欧拉项目练习题吧: 题目015

How many routes are there through a 20[Project Euler] 来做欧拉项目练习题吧: 题目01520 grid? 

 

问题分析

这个题需要一点点观察能力:

观察2*2的方格,以左上角为起点,右下角为终点,形成的所有路径刚好可以构成一棵二叉树。

(不走回头路,并且以经过的方格上的节点为树节点,其中方格左上角为根节点,叶子节点始终是方格右下角)。

而路径条数也就是树的叶子节点个数。

用Count[A]表示树A的叶子节点个数,Left,Right表示左右子树.那么Count[A] = Count[Left] + Count[Right]

OK,问题就变得很简单了,一个递归算法就可以解决。

此后的问题,就是优化递归算法(创建一个缓冲区),减少重复运算,否则速度是不可接受的。

#include <stdio.h>
#define SZ    21        //20*20, index from 0 to 20, so size is 21 
#define END (SZ-1)
long long grid[SZ][SZ];
long long test(int i, int j)
{
int record = grid[i][j];
if(record!=0)
{
return record;
}
if(i==END && j==END)
{
return 1;
}
long long left=0, right=0, total=0;
int  ni=i+1, nj=j+1; //ni: next i
if(ni<SZ)
{
left = test(ni, j);
grid[ni][j] = left;
}
if(nj<SZ)
{
right = test(i, nj);
grid[i][nj] = right;
}
total = left+right;
grid[i][j] = total;
return total;
}
int main()
{
printf("path count: %lld\n", test(0,0));
return 0;
}

速度挺快的:

real    0m0.004s

user    0m0.001s

sys     0m0.003s