算法通过村第十三关-术数|黄金笔记|数论问题

news2024/11/15 10:31:10

文章目录

  • 前言
  • 辗转相除法
  • 素数和合数
  • 埃氏筛选法
  • 丑数问题
  • 总结


前言


提示:难过的人伤心的人、在生活里面对困境的人、即将抑郁的人、从外面很难看出异样,人的心里却可能有一些裂痕。只是人不会再表面裂开。 --栾颖新《那个苹果也很好》

数论是一个很重要的学科,覆盖领域极广,小到小学的智力题目,大到世界顶级科学家都一直在研究的问题,也是因为其难度跨度非常大。在程序设计里面,也经常会出现数论问题的讨论,但是一般这些问题都比较基础,例如:素数问题、幂、对数、阶乘、幂运算、初等代数、几何问题、组合数学等等。这些问题中,组合数学等适合在回溯中讲解。几何问题过于繁琐,不利于做题。这里我们主要讨论素数和合数的问题来讲解,后续找到适合的题目在继续补充。

辗转相除法

辗转相除法又叫做欧几里得算法,是公元前300年左右的希腊数学家欧几里得在他的著作《几何原本》提出的。最大公约数(greatest common divisor 简称gcd),是指几个数的共有的因数之中最大的一个,例如8和12的最大公因数是4,记作gcd(8,12) = 4。辗转相除法的最重要的原则是,如果 r 是 a / b 的余数,则gcd(a,b) = gcd(b,r)。例如计算gcd(546,429):

gcd(546,429):

546 = 1(429) + 117
429 = 3(117) + 78
117 = 1(78) + 39  
78  = 2(39) 
因此:
gcd(546,429)
=gcd(429,117)
=gcd(117,78)
=gcd(78,39)  
=39    

该规则的证明可以,查一下相关资料,这里附上相关链接:[辗转相除法 - 维基百科,自由的百科全书 (wikipedia.org)]

在这里插入图片描述
我们这里看下如何利用循环,实现该代码:

    /**
     * 方法1: 循环实现辗转相除法
     *
     * @param a
     * @param b
     * @return
     */
    public static int gcd1(int a, int b) {// 循环实现
        // 保留余数
        int k = 0;
        do{
            // 拿到余数
            k = a % b;
            // 保留除数
            a = b;
            // 余数赋值给被除数
            b = k;
            // 注意循环条件
        }while(k != 0);
        // 最终返回除数
        return a;
    }

递归的方式也好解决:

    /**
     * 方法2:递归实现辗转相除法
     *
     * @param a
     * @param b
     * @return
     */
    public static int gcd2(int a, int b) {
        // 直到满足此条件逆归退出
        if (b == 0) {
            return a;
        }
        if (a < 0) {
            return gcd2(-a, b);
        }
        if (b < 0) {
            return gcd2(a, -b);
        }
        return gcd2(b, a % b);
    }

素数和合数

我们看下素数和合数的问题。素数又称为质数,素数首先要满足大于等于2,并且除了1和它本身之外,不能被任何其他自然数整除。其他数都是合数。比较特殊的是1既不是素数也不是合数。2是唯一的同时为偶数和素数的数字。

有了定义,自然第一个问题是怎么判断一个正整数是否为素数。题目要求:给定一个正整数 n ( n < 10 ^9),判断它是否为素数。

基本上的方式是从2开始一次与n取余做测试,看是否出现 n % i == 0 的情况,如果出现了,则说明当前的 n 能被i整除,没有就不是。理论上这需要一直测试到 n - 1,都不是才说明它是素数。

在这里插入图片描述

而事实上也并不需要测试那么多,只要从 2 开始遍历一直到 n ^ (1/2) 就可以了,不用执行到 n - 1.这个使用明确的数学证明的,这里就不做赘述,如果不明白的话,可以查阅资料学习一下。所以代码实现也很简单:

    /**
     * 判断素数基本写法
     *
     * @param num
     * @return
     */
    public static boolean isPrime(int num) {
        // 这里取算术平方根  2 
        int max = (int) Math.sqrt(num);
        for (int i = 2; i <= max; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

基于该基础就可以造一些相关的题目了,推荐:

204. 计数质数 - 力扣(LeetCode)

用上述的方法嵌套一下就可以实现:

   public int countPrimes(int n) {
        int count = 0;
        for(int i = 2; i < n; i++){
            if(isPrime(i)){
                count++;
            }
        }
        return count;
    }

这个计算小的数据还行,但是计算比较大的数据就要考虑超时问题了,性能不好。我们接着往下看。

埃氏筛选法

为了高效的解决上述问题,有个筛选的方法:

埃拉托斯特尼筛法(希腊语:κόσκινον Ἐρατοσθένους,英语:sieve of Eratosthenes),简称埃氏筛,也称素数筛,是简单且历史悠久的筛法,用来找出一定范围内所有素数。

原理是从2开始,将每个素数的各倍数标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。此为这个筛法和试除法不同的关键之处,后者是以素数来测试能否整除每个待测数。

素数筛是列出所有小素数的有效方法,得名于古希腊数学家埃拉托斯特尼,并且描述在另一位古希腊数学家尼科马库斯所著的《算术入门》中。

作为现代筛法基础的勒让德筛法是埃拉托斯特尼筛法的简单推广。
在这里插入图片描述
详细列出算法如下:

  1. 列出2以后所有数:
    • 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  2. 标记第一个质数2:
    • 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  3. 用红色标记2的倍数:
    • 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  4. 如果最大数不大于最后一个标出的素数的平方,那么剩下的所有的数都是质数,否则回到第二步。

看图:

在这里插入图片描述

    public int countPrimes(int n) {
        int[] primes = new int[n];
        int ans = 0;
        // 初始化数组
        Arrays.fill(primes,1);
        for(int i = 2; i < n; i++){
            if(primes[i] == 1){
                ans ++;
                // 筛选掉其他
                if((long) i * i < n){
                    for(int j = i*i; j < n; j+= i){
                        primes[j] = 0;
                    }
                }
            }
        }
        return ans;
    }

这个是经典的拿空间换时间的方法,想想一下这种场景在什么场合还可以用到。下面我们看看关于丑数的问题。

丑数问题

参考题目介绍:LCR 168. 丑数 - 力扣(LeetCode)
在这里插入图片描述
根据丑数的定义,0 和负整数一定不是丑数。

当 n > 0时,若 n 时丑数, 则 n 可以写成 n = 2 ^ a + 3 ^ b + 5 ^ c 的形式,其中 a, b, c 都是非负整数。特别是如果a、b、c 都为0 的时候, n == 1;

为了判断 n 是否满足上述形式,可以对n 反复除以 2、3、5.直到 n 不再包含质因数 2 ,3,5。如果剩下的数等于1,则说明 n 不包括其他质因数,是丑数; 否则说明 n 包含其他质因数,不是丑数。

所以代码可以这样写:

     /**
     * 第一种方法,直接计算比较
     *
     * @param index
     * @return
     */
    public static boolean isUgly(int index) {
        if (index < 0){
            return  false;
        }
        int[] factors = {2,3,5};
        for(int factor : factors){
            while(index % factor == 0){
                index /= factor;
            }
        }
        return index == 1;
    }

思考一下,这里如果采用上面所说的埃氏筛选方法要怎么处理,发动一下脑筋。


总结

提示:辗转相除法;素数和合数;求解素数计算;丑数;筛法:


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/

如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~

也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1080423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable diffusion 用DeOldify给黑白照片、视频上色

老照片常常因为当时的技术限制而只有黑白版本。然而现代的 AI 技术,如 DeOldify,可以让这些照片重现色彩。 本教程将详细介绍如何使用 DeOldify 来给老照片上色。. 之前介绍过基于虚拟环境的 基于DeOldify的给黑白照片、视频上色,本次介绍对于新手比较友好的在Stable diff…

2023年中国非血管介入手术无源耗材发展现状、竞争格局及行业市场规模[图]

非血管介入手术是指通过人体自然腔道或通过人体的小切口接近病灶而无需进入血管系统的微创手术&#xff0c;内窥镜、有源医疗器械及无源耗材则是该手术中最常用的医疗器械。非血管介入手术无源耗材主要包括导丝、球囊导管、取石网篮、封堵导管及鞘管。 非血管介入手术无源耗材…

LeetCode【739】每日温度

题目&#xff1a; 思路&#xff1a; https://www.bilibili.com/video/BV1PJ411H7P7/?spm_id_from333.337.search-card.all.click&vd_source2f682a60feabf0f730ad09e0f980ce83 单调栈 思考&#xff1a; 解决栈类问题&#xff0c;思考入栈&#xff0c;出栈条件&#xff1b;…

vue设置页面超时15分钟自动退出登录

需求&#xff1a;用户登录后&#xff0c;如果长时间未操作页面这个时候需要自动退出登录回到登录页面。 注意点&#xff1a;这里我们如果把超时的时间放到浏览器里面存储&#xff0c;我们要放到本地存储里面localStorage里面 Vue设置长时间未操作登录以后自动到期返回登录页 …

重生奇迹MU玛雅宝石的获取方法

在打斗游戏中重生奇迹MU游戏最好玩&#xff0c;并且游戏里面有很多的宝石&#xff0c;比如玛雅宝石、灵魂宝石以及创造宝石等等&#xff0c;这些宝石的作用非常强大&#xff0c;玩家必须要懂得如何利用这些宝石。 那么是否了解玛雅宝石呢&#xff0c;玛雅宝石应该算是最经典的…

为什么选择虚拟展会展览?了解虚拟展会展览的应用领域

引言&#xff1a; 相较于传统的实体展览&#xff0c;虚拟展会展览具有吸引力和便捷性&#xff0c;能够在全球范围内进行宣传活动。这种创新形式不仅能够降低成本、扩大受众范围&#xff0c;还能够提供没有过的互动性和数据分析。 一&#xff0e;虚拟展会展览简介 虚拟展会展览…

TikTok变现的5个高效策略:打造成功创作者之路

短视频平台TikTok已经成为全球范围内最受欢迎的社交媒体之一&#xff0c;吸引了数亿用户。对于创作者而言&#xff0c;TikTok不仅是一个分享创意和娱乐的平台&#xff0c;还是一个潜在的收入来源。本文Nox聚星将和大家探讨TikTok的变现策略&#xff0c;揭示其中的关键秘诀和策略…

京东数据平台:2023年京东营养保健品市场销售数据分析

随着十一长假结束&#xff0c;市场端也开始了一系列的消费数据回顾和复盘。从现有数据表现来看&#xff0c;营养保健品市场的增长备受关注。 近日&#xff0c;京东消费及产业发展研究院与《经济日报》联合整合了相关数据。数据显示&#xff0c;2023年中秋福利采购季期间&#…

class类实现Serializable接口生成serialVersionUID

前言 我在class类实现了Serializable接口&#xff0c;发现把鼠标放在这个类名上&#xff0c;然后键盘输入altenter键没有生成serialVersionUID的提示 解决 找到Editor下边的Inspections&#xff0c;然后搜索UID&#xff0c;把如下截图中的勾选即可 效果 鼠标光标放在类名上&am…

C/C++之自定义类型(结构体,位段,联合体,枚举)详解

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 个人主页&#xff1a;点我进入主页 …

使用 KubeSkoop exporter 监测和定位容器网络抖动问题

作者&#xff1a;遐宇、溪恒 本文是 8 月 17 日直播的文字稿整理&#xff0c;文末可观看直播回放。除去文章内容外&#xff0c;还包括针对实际网络问题的实战环节。 容器网络抖动问题发生频率低&#xff0c;时间短&#xff0c;是网络问题中最难定位和解决的问题之一。 不仅如…

Java基于SpringBoot的学生就业管理信息系统

文章目录 1. 简介2. 技术栈3. 总体设计4 系统设计4.1前台功能模块4.2后台功能模块4.2.1管理员功能 六 源码咨询 1. 简介 Java基于SpringBoot的学生就业管理信息系统&#xff0c;本次设计任务是要设计一个就业信息管理系统&#xff0c;通过这个系统能够满足就业信息管理功能。系…

【接口测试】如何在 Eolink Apilkit 中使用 cookie ?

什么是 Cookie &#xff1f; Cookie是一种在网站之间传递的小型文本文件&#xff0c;用于存储用户的个人信息和偏好设置。当您访问一个网站时&#xff0c;网站会将Cookie存储在您的浏览器中&#xff0c;并在您下次访问该网站时读取该Cookie。这样&#xff0c;网站可以记住您的…

【Spring AOP】Spring AOP 详解

Spring AOP 详解 一. 什么是 AOP二. AOP 组成切面&#xff08;Aspect&#xff09;连接点&#xff08;Join Point&#xff09;切点&#xff08;Pointcut&#xff09;通知&#xff08;Advice&#xff09; 三. Spring AOP 实现1. 添加 AOP 框架⽀持2. 定义切面和切点3. 定义相关通…

nginx windows安装部署,代理转发配置

一、安装 1、nginx官网下载 windows版本 nginx官网 下载后解压到本地 2、在nginx的配置文件是conf目录下的nginx.conf&#xff0c;默认配置的nginx监听的端口为80&#xff0c;如果本地电脑的80端口有被占用&#xff0c;如果本地80端口已经被使用则修改成其他端口。如下&…

【吴恩达深度学习】

第一周 1、修正线性单元ReLU 第二周、Logistic回归 1、样本矩阵X&#xff1a; 是一个m*nx的矩阵&#xff0c;表示m个样本&#xff08;一个竖列代表一个样本&#xff09;&#xff0c;每个样本有nx个特征。 2、标签矩阵Y&#xff1a;[y1,y2,y3,ym] m个训练样本分别对应的标签…

C++程序员必修第一课【C++基础课程】01:安装C++开发环境

1 本课主要内容&#xff1a; 了解 C 开发相关基础概念学会在 Windows10 上安装 Visual Studio 2019免费社区版新建第一个 "Hello World" C 程序&#xff0c;验证 C 开发环境 2 主要知识点&#xff1a; C 开发环境是同时指操作系统和C开发工具操作系统主要有 Window…

软件开发人员 Kubernetes 入门指南|Part 1

Kubernetes 是一个用于部署和管理容器的编排系统。使用 Kubernetes&#xff0c;用户可以通过自动执行管理任务&#xff08;例如在跨节点间扩展容器并在容器停止时重新启动任务&#xff09;&#xff0c;在不同环境中可靠地运行容器。 Kubernetes 提供的抽象可以让你从 Pod&am…

二维码智慧门牌管理系统:提升社会治理水平,创新市民服务方式

文章目录 前言一、适应市域社会治理现代化二、解决地名地址管理核心问题三、拓展多元化服务 前言 随着科技的不断发展&#xff0c;社会治理的方式和方法也在不断更新和升级。近年来&#xff0c;市域社会治理现代化已成为社会发展的必然趋势&#xff0c;而二维码智慧门牌管理系…

011:获取上证50的所有股票代码,并下载各个股K线数到excel表中

我们结合《获取上证50的所有股票代码》&#xff0c;《根据股票代码和起始日期获取K线数据到excel表》两文中的脚本&#xff0c;搞出新的脚本&#xff1a; import tkinter as tk from tkinter import messagebox from tkcalendar import Calendar import pandas as pd import…