Project Euler15 给定一个20*20的方格,从左上角到右下角的路径有多少条?(只允许向右和向下走)

本文探讨了Project Euler第15题的解决方案,即如何计算一个20*20的网格中从左上角到右下角的路径数量。通过递推法,提出了两种算法:一是基于递推公式f(n,n)=f(n-1,n)+f(n,n-1);二是利用排列组合原理,得出f(n,n)=c(n,n+n)。并给出了使用递推法的C语言实现代码,欢迎交流优化建议。" 132285377,19671681,Java实现列置换密码加密解密算法详解,"['java', '算法', '信息安全']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们来讨论一下2*2方格的情况:

从结点1到结点9的走法:

1-2-3-6-9

1-2-5-6-9

1-2-5-8-9

1-4-7-8-9

1-4-5-6-9

1-4-5-8-9

共有6种不同的走法,仔细的读者会发现,在结点3,6,7,8到结点9的通道只有一种,是的,这将会是以后解决问题的关键之一。

现在我们将方格数推广到n,定义f(n,n)为结点(0,0)到结点(n,n)的通道数。

算法如下:

方法一:递推法

  • 递推公式为f(n,n)=f(n-1,n)+f(n,n-1);
  • 初始化条件:当0 <= i <= n,f(n,i)=1,f(i,n)=1。(初始条件的寻找,还得看读者的观察能力了)

方法二:排列组合

  • f(n,n)=c(n,n+n),其中c(n,n+n)表示n+n中取n

现在我只研究方法一,实现的代码如下:

#include <iostream>
#include <TIME.H>
using namespace std;
#define MAX_X 21
#define MAX_Y 21
/*递归*/
_int64 Recursion()
{
	_int64 a[MAX_X][MAX_Y] ;
	for(int i=0;i<=MAX_X-1;i++)
	{
		a[MAX_X-1][i]=1;
		a[i][MAX_Y-1]=1;
	}
	for (int j=MAX_X-2;j>=0;--j)
		for(int i1=MAX_Y-2;i1>=0;i1--)
			a[j][i1]=a[j+1][i1]+a[j][i1+1]
要判断一个数是否为质数,可以使用几种常见的算法。其中一种简单但效率较低的方法是对从2到该数平方根的所有整数进行除法检查,如果都不能整除,那么这个数就是质数。另一种更高效的方法是称为“埃拉托斯特尼筛法”(Sieve of Eratosthenes),但这里我们专注于基本的直觉方法。 以下是一个简单的C++函数,用于判断一个数是否为质数: ```cpp #include <cmath> bool isPrime(int n) { if (n <= 1) { return false; // 1不是质数 } else if (n == 2) { return true; // 2是唯一的偶数质数 } else if (n % 2 == 0) { return false; // 偶数除了2以外都不是质数 } else { for (int i = 3; i <= std::sqrt(n); i += 2) { // 只需检查奇数因子 if (n % i == 0) { return false; } } return true; } } ``` 在这个函数中,首先排除小于等于1的数字(因为它们不是质数)。然后处理特殊情况:2是唯一的偶数质数,所以如果是偶数但不等于2,则直接返回false。接着遍历从3开始的奇数,直到达到`n`的平方根(因为大于这个数的因子肯定不会小于它的平方根),如果找到能整除`n`的因子,说明`n`不是质数。 对于像Project Euler这样的在线平台,可能需要优化代码以处理更大的数值,比如使用“Miller-Rabin素性测试”或“Baillie-PSW测试”,这些方法虽然复杂些,但在理论上保证了较高的正确性更快的速度。如果你对这些高级算法感兴趣,我可以进一步介绍。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值