数论——绝对素数、素数筛法、埃氏筛法、欧拉筛法、最大公约数

news2024/9/28 14:47:21

绝对素数

绝对素数是指一个素数在其十进制表示下,无论是从左向右读还是从右向左读,所得到的数仍然是素数。

例如,13 是一个素数,从右向左读是 31,31 也是素数,所以 13 是一个绝对素数。

#include <iostream>
#include <cmath>
using namespace std;
bool isPrime(int num) {
    if (num < 2) {
        return false;
    }
    for (int i = 2; i <= sqrt(num); i++) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

bool isAbsPrime(int num) {
    int reversedNum = 0, temp = num;
    while (temp > 0) {
        reversedNum = reversedNum * 10 + temp % 10;
        temp /= 10;
    }
    return isPrime(num) && isPrime(reversedNum);
}

int main() {
    int num;
    while(cin >> num){
    if (isAbsPrime(num)) {
        cout << num << " 是绝对素数" << endl;
    }
    else {
        cout << num << " 不是绝对素数" << endl;
    }
    }
    return 0;
}

函数 isPrime:用于判断一个数是否为素数。

如果数字小于 2 ,直接返回 false ,因为 0 和 1 不是素数。从 2 到该数的平方根进行遍历,如果能被整除则返回 false ,遍历结束都不能整除则返回 true 。

函数 isAbsPrime:用于判断一个数是否为绝对素数。

首先定义两个变量,reversedNum 用于存储反转后的数字,temp 用于临时存储原始数字。通过一个循环将数字反转,每次取出原数字的最后一位加到 reversedNum 上,并将原数字除以 10 然后判断原始数字和反转后的数字是否都是素数,如果都是则返回 true ,否则返回 false 。

main 函数:定义一个整数 num 用于接收输入。通过一个 while 循环不断读取输入的数字调用 isAbsPrime 函数来判断输入的数字是否为绝对素数,并根据结果输出相应的信息。

证明:绝对素数的各位上不可以同时出现1,3,7,9

假设存在一个绝对素数,其各位上同时出现了 1、3、7、9。由于是绝对素数,那么其反转后的数也是素数。考虑数字的末尾数字,如果末尾是 1,反转后末尾是 1 ,但如果末尾是 3、7、9 ,反转后末尾变为 3、7、9 。对于以 3、7、9 结尾的数,必然能被 3 整除(一个数各位数字之和能被 3 整除,这个数就能被 3 整除)。

例如,假设这个数是 abc9 ,反转后是 9cba ,那么 9cba 各位数字之和为 9 + c + b + a ,因为 9 能被 3 整除,所以只要 c + b + a 能被 3 整除,9cba 就能被 3 整除,不是素数。同理,对于以 3、7 结尾的情况也能类似推导。所以,绝对素数的各位上不可以同时出现 1、3、7、9 。

整数唯一分解定理

每个大于 1 的正整数都可以唯一地表示为若干个质数的乘积,且这些质数按照从小到大的顺序排列,其指数也都是唯一确定的。

vector<int> factor(int x) {
    vector<int> ret;
    for (int i = 2; i * i <= x; ++i)
        while (x % i == 0) {
            ret.push_back(i);
            x /= i;
        }
    if (x > 1)
        ret.push_back(x);
    return ret;
}

数论基础:它是数论研究中的基础定理,为许多其他定理和问题的解决提供了关键的理论依据。

简化问题:在解决一些涉及整数性质和运算的问题时,将整数分解为质因数的乘积可以使问题变得更加清晰和易于处理。

密码学:在现代密码学中,尤其是公钥密码体制,如 RSA 算法,整数的唯一分解性质起到了核心作用。

素数筛法

素数筛法是一种用于找出一定范围内素数的算法。

埃氏筛法思想
  • 基本思路:先将 2 到指定上限的所有数放入一个数组。从 2 开始,将其倍数标记为合数。然后遍历到下一个未标记的数,重复这个过程,直到遍历完所有小于等于上限的数。
  • 例如,要找出 1 到 100 之间的素数。首先标记 2 的倍数(4、6、8、... 、100)为合数。然后处理 3,标记 3 的倍数(6、9、12、... )为合数。接着处理 5 ,以此类推,最后未被标记的就是素数。

const int N = 1e7;
bool isprime[N + 1];
void eratos(int n) {
	int i, j;
	isprime[0] = isprime[1] = false;
	for (i = 2; i <= n; i++)
		isprime[i] = true;
	for(i=2;i*i<=n;++i)
		if (isprime[i]) {
			for (j = i * i; j <= n; j += i)
				isprime[j] = false;
		}
}
#include <iostream>
#include <vector>
using namespace std;
void sieveOfEratosthenes(int n) {
    vector<bool> isPrime(n + 1, true);
    for (int p = 2; p * p <= n; p++) {
        if (isPrime[p]) {
            for (int i = p * p; i <= n; i += p) {
                isPrime[i] = false;
            }
        }
    }
    for (int p = 2; p <= n; p++) {
        if (isPrime[p]) {
            std::cout << p << " ";
        }
    }
}
int main() {
    int n ;
    cin >> n;
    cout << "1 到 " << n << " 之间的素数为: ";
    sieveOfEratosthenes(n);
    return 0;
}

筛法优化素因数分解
const int N = 1e7;
bool isPrime[N + 1];
int minFactor[N + 1];
void eratos(int n) {
	int i, j;
	isPrime[0] = isPrime[1] = false;
	minFactor[0] = minFactor[1] = -1;
	for (i = 2; i <= n; ++i) {
		isPrime[i] = true;
		minFactor[i] = i;
	}
	for (i = 2; i * i <= n; i++) {
		if (isPrime[i]) {
			for (j = i * i; j <= n; j += i) {
				isPrime[j] = false;
				if (minFactor[j] == j)
					minFactor[j] = i;
			}
		}
	}
}
vector<int>factor(int x) {
	vector<int> ret;
	while (x > 1) {
		ret.push_back(minFactor[x]);
		x /= minFactor[x];
	}
	return ret;
}
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
bool isPrime(int a) {
if (a < 2)
    return false;
for (int i = 2; i * i <= a; i++) {
    if (a % i == 0)
        return false;
}
return true;
}
int main() {
    int n;
    while (cin >> n) {
        vector<int> primes; // 分解质因数
        for (int i = 2; i * i <= n; ++i) {
            while (n % i == 0) {
                primes.push_back(i);
                n /= i;
            }
        } // 如果n是质数且大于2
        if (n > 2)
            primes.push_back(n); // 打印质因数
        cout << "Prime factors: ";
        for (int prime : primes) {
            cout << prime << " ";
        }
        cout
            << endl; // 如果需要计算质因数的乘积(通常这将是原始数n,除非有重复因子被忽略)
        long long product = 1;
        for (int prime : primes) {
            product *= prime;
        }
    }
    return 0;
}

  1. isPrime 函数

    • 目的:用于判断一个整数是否为质数。
    • 逻辑:如果数字小于 2 则不是质数。然后从 2 开始到该数的平方根进行遍历,如果能被整除则不是质数,否则是质数。
  2. main 函数

    • 输入部分:通过 while (cin >> n) 不断获取用户输入的整数 n
    • 分解质因数部分:
      • 使用一个循环从 2 到 n 的平方根,找到能整除 n 的数 i ,将其添加到 primes 向量中,并不断更新 n 的值。
      • 如果最后 n 仍然大于 2,说明 n 本身也是一个质因数,将其添加到 primes 中。
    • 输出部分:
      • 首先输出质因数,通过遍历 primes 向量并打印每个质因数。
      • 然后计算质因数的乘积,通过遍历 primes 向量并累乘每个质因数。
欧拉筛法(线性筛)
  • 基本思路:通过维护每个数的最小质因数来筛选素数。对于每个数,只通过其最小质因数来筛去合数。

#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 1000005;
vector<int> primes;
bool isNotPrime[MAXN];
void EulerSieve(int n) {
    for (int i = 2; i <= n; ++i) {
        if (!isNotPrime[i]) {
            primes.push_back(i);
        }
        for (int j = 0; j < primes.size() && i * primes[j] <= n; ++j) {
            isNotPrime[i * primes[j]] = true;
            if (i % primes[j] == 0) {
                break;
            }
        }
    }
}

int main() {
    int n;
    while (cin >> n) {
        EulerSieve(n);
        cout << "小于等于 " << n << " 的质数有: " << endl;
        for (int prime : primes) {
            cout << prime << " ";
        }
        cout << std::endl;
        primes.clear();  // 每次输入新的 n 之前清空 primes 向量,避免结果累加
    }
    return 0;
}
  1. EulerSieve 函数

    • 这个函数的目的是使用欧拉筛法找出小于等于给定值 n 的所有质数。
    • 外层的 for 循环从 2 遍历到 n 。
    • 如果当前数字 i 未被标记为非质数(isNotPrime[i] 为 false ),则将其添加到 primes 向量中,因为它是一个质数。
    • 内层的 for 循环用于标记当前数字 i 与已找到的质数的乘积为非质数。但如果 i 能被当前的质数整除,就通过 break 退出内层循环,这是为了保证每个合数只被其最小质因数筛掉。
  2. main 函数

    • 首先定义了一个整数 n 用于接收用户输入。
    • 通过 while (cin >> n) 不断获取用户输入的数字。
    • 每次输入新的 n 后,调用 EulerSieve 函数进行质数的筛选。
    • 然后输出小于等于 n 的所有质数,并在输出前添加提示信息,且换行。
    • 最后通过 primes.clear() 清空 primes 向量,为下一次输入和筛选做好准备。
前n个数的约数之和

#include <iostream>
using namespace std;

// 计算一个数的约数之和
int sumOfDivisors(int num) {
    int sum = 0;
    for (int i = 1; i * i <= num; i++) {
        if (num % i == 0) {
            sum += i;
            if (i != num / i) {
                sum += num / i;
            }
        }
    }
    return sum;
}

// 计算前 n 个数的约数之和
int sumOfDivisorsForFirstN(int n) {
    int totalSum = 0;
    for (int i = 1; i <= n; i++) {
        totalSum += sumOfDivisors(i);
    }
    return totalSum;
}

int main() {
    int n;
    while (cin >> n) {
        int result = sumOfDivisorsForFirstN(n);
        cout << "前 " << n << " 个数的约数之和为: " << result << endl;
    }

    return 0;
}
  1. sumOfDivisors 函数

    • 从 1 到该数的平方根进行遍历。
    • 如果 num 能被 i 整除,就将 i 加到和中。
    • 如果 i 不等于 num / i (即 i 和 num / i 是不同的约数),则将 num / i 也加到和中。
  2. sumOfDivisorsForFirstN 函数

    • 通过一个循环从 1 到 n ,对每个数调用 sumOfDivisors 函数计算其约数之和,并累加到 totalSum 中。
BZOJ1053——反素数

反素数(又称逆素数)是指一个正整数满足:对于任意小于它的正整数,其约数个数都小于该数的约数个数。

[HAOI2007]反素数ant - 题目详情 - BZOJ by HydroOJ

#include <iostream>
#include <cmath>
using namespace std;

const int N = 1e5 + 5;

int n, cntp, pri[N], vis[N], ans, mx;

void dfs(int i, int cur, int cnt) {
    if (cnt > mx) {
        mx = cnt;
        ans = cur;
    }
    else if (cnt == mx) {
        ans = min(ans, cur);
    }
    if (i > min(10, cntp)) {
        return;
    }
    dfs(i + 1, cur, cnt);
    int num = pri[i];
    for (int j = 1; 1LL * cur * num <= n; j++) {
        cur *= num;
        dfs(i + 1, cur, cnt * (j + 1));
    }
}

int main() {
    cin >> n;
    int k = sqrt(n);
    for (int i = 2; i <= k; i++) {
        if (!vis[i]) {
            pri[++cntp] = i;
        }
        for (int j = 1; pri[j] * i <= k; j++) {
            vis[pri[j] * i] = 1;
            if (i % pri[j] == 0) {
                break;
            }
        }
    }
    dfs(1, 1, 1);
    cout << ans << endl;
    return 0;
}

首先,定义了一些常量和变量,包括问题规模 N ,整数 n ,质数数量 cntp ,质数数组 pri ,标记数组 vis ,最终答案 ans 以及最大值 mx 

在 dfs 函数中:

  • 首先判断当前的计数 cnt 是否大于最大值 mx ,如果是则更新 mx 和 ans ;如果 cnt 等于 mx ,则更新 ans 为更小的值。
  • 接着,如果当前的搜索层数 i 超过了限制(min(10, cntp) ),则返回不再继续搜索。
  • 然后进行两种情况的搜索:
    • 不选择当前层的质数,直接递归到下一层。
    • 选择当前层的质数,通过一个循环不断乘以当前质数,更新当前数值 cur 和计数 cnt ,并递归到下一层。

在 main 函数中:

  • 首先读取输入的整数 n 。
  • 然后通过两层循环来找出小于等于 sqrt(n) 的质数,并存储在 pri 数组中,同时标记相应的合数。
  • 最后调用 dfs 函数进行深度优先搜索,并输出最终的答案 ans 。
最大公约数

高精度数的二进制求gcd(a,b)
int gcd(int m, int n) {
    if (m == n)
        return m;
    if (m < n)
        return gcd(n, m);
    if (m & 1 == 0)
        return (n & 1 == 0) ? 2 * gcd(m >> 1, n >> 1) : gcd(m >> 1, n);
    return (n & 1 == 0) ? gcd(m, n >> 1) : gcd(n, m - n);
}

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

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

相关文章

小红书无货源选品逻辑和爆品思路(图文解析)

了解用户的购物习惯、需求偏好以及日常搜索行为&#xff0c;是选品的重要前提。选品不是嘴巴一张这么简单的事情&#xff0c;是需要通过长期积累及网感来分析。记住&#xff1a;人-货-场&#xff0c;这个原则。比如明知道小红书上的年前女性用户多&#xff0c;你偏偏来卖一台挖…

悠易科技周文彪:创始人专注度很重要,一旦战略分散无法形成合力 | 中国广告营销行业资本报告深访④

周文彪&#xff08;悠易科技CEO&#xff09; 问&#xff1a;近年来广告营销行业主要的融资事件发生在营销技术领域。您对此有何评论&#xff1f; Roy&#xff1a;Adtech最早从2007年前后开始发展&#xff0c;差不多十年的时间&#xff0c;因为广告技术帮助企业成长&#xff0c…

【时时三省】unity test 测试框架 使用 code blocks 移植(核心文件:unity.c, unity_fixture.c)

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 目录 1&#xff0c;移植介绍 2&#xff0c;使用 Code::Blocks 17.12 创建工程 3&#xff0c;搬移文件入工程目录 4&#xff0c;更改代码 5&#xff0c;向工程添加文件 6&#xff0c;运…

解锁PDF新姿势:2024年PDF转图片工具精选

随着数字化办公的普及和文档处理需求的日益增长&#xff0c;PDF转图片工具已成为日常工作中不可或缺的一部分。这些工具不仅帮助用户轻松地将PDF文件转换为图片格式&#xff0c;还提供了丰富的编辑、转换和批量处理功能&#xff0c;极大地提高了工作效率。 1.福昕PDF转换大师&…

数据结构实验报告-栈

实 验 三 报 告 一、实验目的 1.掌握栈的定义、特点、逻辑结构&#xff0c;理解栈的抽象数据类型。 2.熟练掌握顺序栈的结构类型定义、特点和基于顺序栈的基本运算的实现。 3.熟练掌握链栈的结构类型定义、特点和基于链栈的基本运算的实现。 4.理解递归算法执行过程中栈的…

ssh网络协议(服务名sshd,端口22)

目录 前言 配置文件&#xff08;/etc/ssh/sshd_config&#xff09; 配置文件内容 自己可以添加的设置&#xff1a; 注意&#xff01;&#xff1a; ssh连接登录演示 scp文件传输 登录验证方式 密码验证登录 秘钥验证登录 配置ssh密钥对验证登录 生成密钥对&#xff…

JavaWeb基础3:会话/过滤器/监听器

JavaWeb基础3&#xff1a;会话/过滤器/监听器 (qq.com)

海尔、希亦、米博洗地机哪个好用?海尔、希亦、米博洗地机实测PK

洗地机相比普通清洁工具&#xff0c;拥有科学的设计&#xff0c;而且清洁技术专业&#xff0c;能够把地面上的污渍、灰尘、毛发等通通清理干净&#xff0c;保持地面光洁。比起手动清理&#xff0c;它还能减少地面和空气的细菌滋生&#xff0c;可以说是居家必备的清洁神器了。不…

C# 实现改造 GooFlow 流程图插件与数据库应用的结合

目录 关于 GooFlow 功能需求 范例运行环境 设计数据表 流程项目表 流程项目节点明细表 流程项目节点审批人表 人员信息表 示例代码 流程图主功能 设置审批人信息 运行结果演示 总结 关于 GooFlow GooFlow 一个基于 Jquery/FontAwesome 的流程图/架构图画图插件&…

探索Python异步编程的秘境:Eventlet的魔力与魅力

文章目录 **探索Python异步编程的秘境&#xff1a;Eventlet的魔力与魅力**第一部分&#xff1a;背景与引言第二部分&#xff1a;Eventlet是什么&#xff1f;第三部分&#xff1a;如何安装Eventlet&#xff1f;第四部分&#xff1a;Eventlet的基本使用第五部分&#xff1a;Event…

如何用ai来完成数据库分析(2)

一样的前言 因一些课程设计要写长篇分析报告&#xff0c;这里借用ai做一篇指导教程&#xff0c;分上下两篇。这篇也会教如何让ai给你你想要的答案&#xff0c;众所周知&#xff0c;现在的ai并不智能&#xff0c;不针对各类厂家&#xff0c;但是放出来的确实表象如此。 但其实…

CMIP6数据处理技术教程

原文链接&#xff1a;CMIP6数据处理技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247611539&idx4&sn3eb0490b72ef694dcd41f6de0b623388&chksmfa827574cdf5fc62372bfcf188ea1ae6e41350ff8469c2940ed097244b205e0dd73f4c8832fa&token616696…

绝对干货!分享把Fildder录制的脚本导出成Jmeter脚本的方法(实测在Fiddler5中有效)

相信做过接口测试的小伙伴都面临过这样的窘境——在没有接口测试文档的情况下&#xff0c;进行接口的压力测试&#xff01;怎么破&#xff1f; 通常的做法都是利用抓包工具&#xff08;以fiddler为例&#xff09;进行抓包&#xff0c;然后把抓包请求手写到压力测试工具中&…

解决Solidworks 2024运行的Windows资源极低,执行此命令可能会导致SOLIDWORKS 失败。

Solidworks Resource Monitor 可供使用的系统内存很低。请关闭一些应用程序以释放资源。即使内存十分充足&#xff0c;也容易出现这些提示&#xff0c;而我个人感觉2024版相比以前版本更容易出现这个问题&#xff0c;这显然是Solidworks本身的Bug。网上普遍流传的解决方法&…

再讲Langchain 提示词模板(PromptTemplate)

在LangChain 0.2中,提示词模板(Prompt Template)是一个非常重要的概念和功能。它允许我们创建结构化和可重用的提示,以便更有效地与语言模型进行交互。 提示词模板的主要作用包括: 结构化提示: 允许我们定义一个固定的提示结构,包含静态文本和动态变量。 参数化: 可以在模板中…

汽车测试-ADAS测试设备RT3000介绍及数据处理

目录 一、分析目的 二、数据采集仪器 三、数据文件 1.数据样本名词解释 2.数据应用 3.简单举例 汽车数据分析示例 1. 行驶轨迹与路径优化 2. 速度与加速度分析 3. 燃油效率与能耗分析 4. 驾驶行为与安全分析 5. 车辆维护与故障诊断 评估导航与定位的准确性。 一、…

测试工程师职业道路管理方向有哪些

目录 01测试组长 测试组长的职责及掌握技能&#xff1a; 测试组长需要掌握的技能&#xff1a; 02测试经理 测试经理具备的职责&#xff1a; 测试经理具备的技能&#xff1a; 03测试总监 测试总监具备的职责&#xff1a; 测试总监具备的技能&#xff1a; 测试工程师管理…

蚓链数字化生态系统:助力企业上下游资源的强大引擎

在当今数字化浪潮汹涌的时代&#xff0c;集团型企业面临着日益复杂的市场环境和激烈的竞争挑战。如何有效地拉通产业上下游资源&#xff0c;实现协同发展&#xff0c;成为了众多企业亟待解决的关键问题。而蚓链数字化生态系统的出现&#xff0c;犹如一道曙光&#xff0c;为集团…

前端工程化12-Git版本控制工具详解

2.1、Git知识概述 理解版本控制工具&#xff0c;聊下他的历史&#xff0c;之后会讲两种版本控制工具的区别&#xff08;集中式|分布式&#xff09;、他的基本环境搭建安装&#xff0c;如何初始化本地仓库&#xff0c;如何往仓库里提交一些东西&#xff0c;文件的话会有那些变化…

文本相似度 HanPL汉语言处理

文章目录 前言需求简介实操开始1. 添加pom.xml依赖2. 文本相似度工具类3. 案例验证4. 验证结果 总结 前言 请各大网友尊重本人原创知识分享&#xff0c;谨记本人博客&#xff1a;南国以南i、 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 需求 当我…