GDPU 竞赛技能实践 天码行空9 数学 卡特兰数

1. 埃式筛法

求区间[2, n]内所有的素数

💖 Main.java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main
{
	static int N = (int) 1e8, cnt = 0;
	static List<Integer> p = new ArrayList<>();
	static boolean[] st = new boolean[N];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		getPrimes(n);
		print();
	}

	private static void print()
	{
		int n = p.size();
		for (int i = 1; i < n; i++)
			if (p.get(i - 1) + 2 == p.get(i))
				System.out.println(p.get(i - 1) + " " + p.get(i));
	}

	private static void getPrimes(int n)
	{
		for (int i = 2; i <= n && i < N; i++)
		{
			if (!st[i])
			{
				p.add(i);
				for (int j = 2; j * i <= n; j++)
					st[i * j] = true;
			}
		}
	}

}

在这里插入图片描述

2. 求第1亿个Fibonacci数

👨‍🏫 参考地址
😋 投机取巧:取模防止溢出
PS:第一亿个斐波那契数肯定是会超长整型的范围,即使用数组存每一位上的数,那需要的容量也未可知

💖 Main.java

public class Main
{
	static long n, p;

//	龟速乘法(快速积)
	static long qmul(long a, long b)
	{
		long res = 0;
		while (b != 0)
		{
			if ((b & 1) == 1)
			{
				res = (res + a) % p;
			}
			a = (a + a) % p;
			b >>= 1;
		}
		return res;
	}

//	矩阵乘法
	static void mul(long[][] a, long[][] b)
	{
//		临时矩阵暂存结果
		long[][] tmp = new long[2][2];
		for (int i = 0; i < 2; i++)
			for (int j = 0; j < 2; j++)
				for (int k = 0; k < 2; k++)
					tmp[i][j] = (tmp[i][j] + qmul(a[i][k], b[k][j])) % p;

//		拷贝
		for (int i = 0; i < 2; i++)
			for (int j = 0; j < 2; j++)
				a[i][j] = tmp[i][j];
	}

//	计算斐波那契数列的第 n 项
	static long F(long n)
	{
//		极端情况
		if (n == 0)
			return 0;

//		根据fn来进行构造矩阵
		// fn,分别为f(1) f(2)
		long[][] f = { { 1, 1 }, { 0, 0 } };
		// 累乘矩阵
		long[][] a = { { 0, 1 }, { 1, 1 } };

//      快速幂
		for (long k = n - 1; k != 0; k >>= 1)
		{
			if ((k & 1) == 1)
				mul(f, a);
			mul(a, a);
		}
		return f[0][0];
	}

	public static void main(String[] args)
	{
		n = (int) 1e8;// 10^8 == 1 亿
		p = Integer.MAX_VALUE; // 由于会爆int long 需要取模
		System.out.println("前20项:");
		for (int i = 0; i < 20; i++)
			System.out.print(F(i) + " ");
		System.out.println();
		System.out.println("第1亿项:" + F(n));
	}
}

在这里插入图片描述

3.Catalan数

即卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中的数列,以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名。现请你写一段程序来计算Catalan数。
输入样例:

5

输出样例:

42

💖 Main.java

import java.util.Scanner;

public class 卡特兰数
{

	static long cal(int n)
	{
		long son = 1;
		long mum = 1;
		for (int i = 2 * n; i > n; i--)
			son *= i;
		for (int i = n; i >= 1; i--)
			mum *= i;
		return son / (mum * (n + 1));
	}

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		System.out.println(cal(n));
	}
}

在这里插入图片描述

4. 摆球

现将大小和形状相同的4个黑色球和4个红色球排成一排,从左边第一个球开始数,不管数几个不球,黑球数不少于红球数的排法有多少种?请编程实现。
卡特兰数的应用

💖 Main.java

public class Main
{
	static int N = 8;
	static long ans = 0;
	static long ans1 = 0;

	public static void main(String[] args)
	{
		dfs(0, 0, 0);

		System.out.println(ans + " " + cal(4));
	}

//	卡特兰数
	static long cal(int n)
	{
		long son = 1;
		long mum = 1;
		for (int i = 2 * n; i > n; i--)
			son *= i;
		for (int i = n; i >= 1; i--)
			mum *= i;
		return son / (mum * (n + 1));
	}

//	暴力枚举
	private static void dfs(int cur, int black, int red)
	{
		if (cur >= 8)
		{
			if (red == 4 && black == 4)
				ans++;
			return;
		}
		if (black > red)
			dfs(cur + 1, black, red + 1);
		dfs(cur + 1, black + 1, red);
	}

}

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值