洛谷每日一题——P1036 [NOIP2002 普及组] 选数、P1045 [NOIP2003 普及组] 麦森数(高精度快速幂)

P1036 [NOIP2002 普及组] 选数

题目描述

[NOIP2002 普及组] 选数 - 洛谷

运行代码

#include <stdio.h>
int n, k, a[25], t;
int ss(int b) {
    int i;
    if (b < 2)
        return 0;
    for (i = 2; i * i <= b; i++)
        if (b % i == 0)
            return 0;
    return 1;
}
void dfs(int num, int sum, int j) {
    int i;
    if (num == k) {
        if (ss(sum))
            t++;
        return;
    }
    for (i = j; i < n; i++)
        dfs(num + 1, sum + a[i], i + 1);
    return;
}
int main() {
    int i;
    scanf("%d %d", &n, &k);
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    dfs(0, 0, 0);
    printf("%d", t);
    return 0;
}
改进后
  • 将判断一个数是否为质数的函数 ss 改名为 isPrime,使其功能更清晰易懂。
  • 在 dfs 函数中,将原本在全局变量中的 k 和数组 a 以及用于计数的 t 作为参数传递进去,这样可以使函数的独立性更强,不需要依赖全局变量,降低了代码的耦合度。
  • 在 isPrime 函数中,使用 sqrt(b) 来代替 i * i <= b,在判断一个数是否为质数时,只需要遍历到该数的平方根即可,这样可以稍微提高一些效率。
#include <stdio.h>
#include <math.h>

// 判断一个数是否为质数
int isPrime(int b) {
    if (b < 2) return 0;
    for (int i = 2; i <= sqrt(b); i++) {
        if (b % i == 0) return 0;
    }
    return 1;
}

// 深度优先搜索函数
void dfs(int num, int sum, int j, int k, int *a, int *t) {
    if (num == k) {
        if (isPrime(sum)) (*t)++;
        return;
    }
    for (int i = j; i < n; i++) {
        dfs(num + 1, sum + a[i], i + 1, k, a, t);
    }
}

int main() {
    int n, k, a[25], t = 0;
    scanf("%d %d", &n, &k);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    dfs(0, 0, 0, k, a, &t);
    printf("%d", t);
    return 0;
}

代码思路

这段代码的主要目的是从给定的一组整数中选取 k 个整数,将它们相加,然后判断相加的和是否为质数,统计满足条件的组合数量。

  1. 数据读取与初始化

    • 在 main 函数中,首先通过 scanf 读取两个整数 n 和 k,其中 n 表示给定的整数数组 a 的长度,k 表示要从数组中选取的整数个数。
    • 接着通过循环使用 scanf 读取数组 a 中的每一个元素。
    • 同时初始化一个变量 t 为 0,用于统计满足条件(即选取的 k 个整数相加和为质数)的组合数量。
  2. 深度优先搜索(DFS)实现组合选取dfs 函数用于实现深度优先搜索来找出所有可能的 k 个整数的组合。它接受几个参数:

    • t:用于统计满足条件的组合数量(通过指针传递,以便在函数内部修改其值)。
    • a:给定的整数数组(从 main 函数传递过来)。
    • k:要选取的整数个数(从 main 函数传递过来)。
    • j:表示下一个可供选取的整数在数组 a 中的索引。
    • sum:表示当前选取的整数相加的和。
    • num:表示当前已经选取的整数个数。
    • 在 dfs 函数内部:
      • 当 num 等于 k 时,说明已经选取了 k 个整数,此时调用 isPrime 函数判断 sum 是否为质数,如果是,则将 t 的值加 1,然后返回。
      • 如果 num 不等于 k,则通过循环从索引 j 开始遍历数组 a,对于每一个元素 a[i],递归调用 dfs 函数,将 num 加 1(表示又选取了一个整数),sum 加 a[i](更新选取的整数相加的和),i + 1(更新下一个可供选取的整数的索引)。
  3. 判断质数函数

    • isPrime 函数用于判断一个数是否为质数。它接受一个整数 b 作为参数。
    • 如果 b 小于 2,则直接返回 0,因为小于 2 的数不是质数。
    • 然后通过循环从 2 开始遍历到 sqrt(b),如果在这个范围内发现 b 能被某个数整除(即 b % i == 0),则返回 0,说明 b 不是质数;如果遍历完整个范围都没有发现这样的数,则返回 1,说明 b 是质数。
  4. 结果输出:最后,在 main 函数中,通过 printf 输出统计得到的满足条件的组合数量 t

综上所述,该代码通过深度优先搜索遍历所有可能的 k 个整数的组合,然后判断每个组合的和是否为质数,从而统计出满足条件的组合数量。

P1045 [NOIP2003 普及组] 麦森数(高精度快速幂)

题目描述

[NOIP2003 普及组] 麦森数 - 洛谷

运行代码

#include <algorithm>
#include <cmath>
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
const int N = 500;
typedef vector<int> VI;
VI a(N), res(N);
int p;
VI mul(VI& a, VI& b) {
    VI t(N * 2);
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
            t[i + j] += a[i] * b[j];
            t[i + j + 1] += t[i + j] / 10;
            t[i + j] %= 10;
        }
    return t;
}
void quick_pow(int p) {
    res[0] = 1, a[0] = 2;
    while (p) {
        if (p & 1)
            res = mul(res, a);
        a = mul(a, a);
        p >>= 1;
    }
    res[0]--;
}
int main() {
    cin >> p;
    printf("%d\n", int(p * log10(2)) + 1);
    quick_pow(p);
    for (int i = 0, k = 499; i < 10; i++) {
        for (int j = 0; j < 50; j++, k--)
            printf("%d", res[k]);
        puts(" ");
    }
    return 0;
}
改进后
  • 在 mul 函数中,将结果向量 t 的初始化大小改为根据输入向量 a 和 b 的大小动态确定,更加灵活且避免了可能的空间浪费。同时,在函数结尾添加了去除前导 0 的操作,使结果更加规范。
  • 在 quick_pow 函数中,将 res 和 a 的初始化放在函数内部,使函数更加独立,不需要依赖全局变量。并且将 res 作为参数传入,这样可以在函数内部直接修改其值,而不是像原来那样通过全局变量来操作。
  • 在 main 函数中,使用 cout 代替 printf,使代码风格更加统一(因为前面已经使用了 iostream 库)。同时,在输出结果时,对超出向量范围的情况进行了处理,即当索引小于 0 时输出 0,保证了输出的完整性。
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

// 高精度乘法函数,计算两个大整数向量的乘积
vector<int> mul(const vector<int>& a, const vector<int>& b) {
    vector<int> t(a.size() + b.size(), 0);
    for (size_t i = 0; i < a.size(); ++i) {
        for (size_t j = 0; j < b.size(); ++j) {
            t[i + j] += a[i] * b[j];
            t[i + j + 1] += t[i + j] / 10;
            t[i + j] %= 10;
        }
    }
    // 去除前导0
    while (t.size() > 1 && t.back() == 0) t.pop_back();
    return t;
}

// 快速幂函数,用于计算2的p次方
void quick_pow(int p, vector<int>& res) {
    res = {1};
    vector<int> a = {2};
    while (p) {
        if (p & 1) res = mul(res, a);
        a = mul(a, a);
        p >>= 1;
    }
    res[0]--;
}

int main() {
    int p;
    cin >> p;

    // 先输出结果的位数
    cout << static_cast<int>(p * log10(2)) + 1 << endl;

    vector<int> res;
    quick_pow(p, res);

    // 输出结果,每50个数字为一行
    for (int i = 0, k = res.size() - 1; i < 10; ++i) {
        for (int j = 0; j < 50; ++j, k--) {
            if (k >= 0) cout << res[k];
            else cout << 0;
        }
        cout << endl;
    }

    return 0;
}

代码思路

这段代码主要实现了两个功能:一是计算并输出 2 的 p 次方减 1 的结果(以高精度整数的形式),二是先输出这个结果的位数。

  1. 高精度乘法函数 mul

    • 目的是实现两个大整数(以 vector<int> 形式存储,每个元素代表整数的一位)的乘法运算。
    • 首先创建一个大小为 a.size() + b.size() 的结果向量 t,初始值都为 0
    • 然后通过两层嵌套的循环遍历两个输入向量 a 和 b 的每一位。对于每一对位 a[i] 和 b[j],将它们的乘积加到 t[i + j] 上。接着处理进位,将 t[i + j] 除以 10 的商加到 t[i + j + 1] 上,同时将 t[i + j] 除以 10 的余数保留在 t[i + j] 上。
    • 最后,通过循环去除结果向量 t 中的前导 0,得到规范的乘法结果并返回。
  2. 快速幂函数 quick_pow

    • 基于快速幂算法来计算 2 的 p 次方。快速幂算法的基本思想是通过不断地将指数减半,同时根据指数的奇偶性来决定是否将当前的中间结果与底数相乘,从而减少乘法运算的次数,提高计算效率。
    • 首先初始化 res 为只包含一个元素 1 的向量,表示 2 的 0 次方结果;初始化 a 为只包含一个元素 2 的向量,表示底数。
    • 然后在循环中,当 p 不为 0 时:
      • 如果 p 是奇数(即 p & 1 为真),则将当前的中间结果 res 与底数 a 相乘,更新 res 的值。
      • 然后将底数 a 自身相乘,更新 a 的值。
      • 最后将 p 除以 2(通过 p >>= 1 实现),继续下一轮循环。
    • 循环结束后,将 res 的第一个元素减 1,得到 2 的 p 次方减 1 的结果。
  3. 主函数 main

    • 首先通过 cin 读取输入的整数 p
    • 接着计算并输出 2 的 p 次方减 1 的结果的位数。根据对数的性质,一个数 N 的位数可以通过 log10(N) 来估算,对于 2 的 p 次方,其位数大约为 p * log10(2),再加上 1 是因为可能存在进位情况,所以通过 cout 输出 int(p * log10(2)) + 1
    • 然后调用 quick_pow 函数计算 2 的 p 次方减 1 的结果,并将结果存储在 res 向量中。
    • 最后,通过两层嵌套的循环将 res 中的结果以每 50 个数字为一行的方式输出。在循环中,先从 res 的末尾开始向前遍历,对于每一行,输出 50 个数字,如果遇到索引小于 0 的情况(即已经遍历完所有数字),则输出 0,保证每行输出的数字数量固定为 50 个。

综上所述,该代码通过高精度乘法和快速幂算法实现了对 2 的 p 次方减 1 的计算和输出,同时也给出了结果的位数估算。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始 blender插件开发

blender 插件开发 文章目录 blender 插件开发环境配置1. 偏好设置中开启相关功能2. 命令行打开运行脚本 API学习专有名词1. bpy.data 从当前打开的blend file中&#xff0c;加载数据。2. bpy.context 可用于获取活动对象、场景、工具设置以及许多其他属性。3. bpy.ops 用户通常…

【若依框架】代码生成详细教程,15分钟搭建Springboot+Vue3前后端分离项目,基于Mysql8数据库和Redis5,管理后台前端基于Vue3和Element Plus,开发小程序数据后台

今天我们来借助若依来快速的搭建一个基于springboot的Java管理后台&#xff0c;后台网页使用vue3和 Element Plus来快速搭建。这里我们可以借助若依自动生成Java和vue3代码&#xff0c;这就是若依的强大之处&#xff0c;即便你不会Java和vue开发&#xff0c;只要跟着石头哥也可…

Java基于SpringBoot+Vue的宠物共享平台的设计与实现(附源码,文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

前端入门一之DOM、获取元素、DOM核心、事件高级、操作元素、事件基础、节点操作

前言 JS是前端三件套之一&#xff0c;也是核心&#xff0c;本人将会更新JS基础、JS对象、DOM、BOM、ES6等知识点&#xff0c;这篇是DOM;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 DOMDOM简介1.1、什么是DOM1…

Python小游戏22——吃豆豆小游戏

运行效果图 【python】代码展示 import pygame import random # 初始化Pygame pygame.init() # 屏幕尺寸 WIDTH, HEIGHT 800, 600 WIN pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("吃豆豆小游戏") # 颜色定义 WHITE (255, 255, 255) B…

「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用

本篇将带你实现一个番茄钟倒计时应用&#xff0c;用户可以设置专注时间和休息时间的时长&#xff0c;点击“开始专注”或“开始休息”按钮启动计时&#xff0c;应用会在倒计时结束时进行提醒。番茄钟应用对于管理时间、提升工作效率非常有帮助&#xff0c;并且还会加入猫咪图片…

2024 网鼎杯 - 青龙组 Web WP

2024 网鼎杯 - 青龙组 WEB - 02 打开容器一个登录界面&#xff0c;随便输入账号密码可以进到漏洞界面 这里有一个发送给boss的功能&#xff0c;一眼xss 有三个接口&#xff1a;/flag 、/update 、/submit /flag &#xff1a;要求boss才能访问&#xff0c;/update &#xf…

【笔记】自动驾驶预测与决策规划_Part6_不确定性感知的决策过程

文章目录 0. 前言1. 部分观测的马尔可夫决策过程1.1 POMDP的思想以及与MDP的联系1.1.1 MDP的过程回顾1.1.2 POMDP定义1.1.3 与MDP的联系及区别POMDP 视角MDP 视角决策次数对最优解的影响 1.2 POMDP的3种常规解法1.2.1 连续状态的“Belief MDP”方法1. 信念状态的定义2. Belief …

ffmpeg 视频滤镜:屏蔽边框杂色- fillborders

滤镜描述 fillborders 官网链接 > FFmpeg Filters Documentation fillborders滤镜有几种方式帮你屏蔽边框的杂色、不好的图案。 滤镜使用 参数 left <int> ..FV.....T. set the left fill border (from 0 to INT_MAX) (default 0)right …

Java基础——类和对象的定义链表的创建,输出

目录 什么是类&#xff1f; 什么是对象? 如何创建链表&#xff1f; 尾插法&#xff1a; 头插法&#xff1a; 输出链表的长度 输出链表的值 什么是类&#xff1f; 创建Java程序必须创建一个类class. .java程序需要经过javac指令将文件翻译为.class字节码文件&#xff0c…

简单的 docker 部署ELK

简单的 docker 部署ELK 这是我的运维同事部署ELK的文档&#xff0c;我这里记录转载一下 服务规划 架构: Filebeat->kafka->logstash->ES kafka集群部署参照: kafka集群部署 部署服务程序路径/数据目录端口配置文件elasticsearch/data/elasticsearch9200/data/elas…

【初阶数据结构篇】二叉树OJ题

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

5分钟科普:AI网关是什么?应用场景是什么?有没有开源的选择?

AI网关的功能及其定义 AI网关位于企业应用与内外部大模型调用的交汇点&#xff0c;能够灵活地将请求转发给内部自建模型或外部大模型服务提供商&#xff0c;甚至海外的服务商。它管理着企业所有的AI出口流量&#xff0c;为企业内的不同团队提供了多方面的优势。 对于开发团队…

Ansys Zemax | 手机镜头设计 - 第 4 部分:用LS-DYNA进行冲击性能分析

该系列文章将讨论智能手机镜头模组设计的挑战&#xff0c;从概念和设计到制造和结构变形分析。本文是四部分系列中的第四部分&#xff0c;它涵盖了相机镜头的显式动态模拟&#xff0c;以及对光学性能的影响。使用Ansys Mechanical和LS-DYNA对相机在地板上的一系列冲击和弹跳过程…

凸优化理论,凸二次规划问题,对偶问题及KKT条件

凸优化理论 ​ 研究凸优化之前我们不妨提出几个小问题&#xff1a; 什么是优化问题&#xff1f;优化问题的解是什么&#xff1f;什么是凸优化问题&#xff1f;凸优化问题的解决方案是什么&#xff1f; 1.1 优化问题 ​ 理解优化问题其实很简单&#xff0c;我们其实从高中事…

实战攻略 | ClickHouse优化之FINAL查询加速

【本文作者&#xff1a;擎创科技资深研发 禹鼎侯】 查询时为什么要加FINAL 我们在使用ClickHouse存储数据时&#xff0c;通常会有一些去重的需求&#xff0c;这时候我们可以使用ReplacingMergeTree引擎。这个引擎允许你存储重复数据&#xff0c;但是在merge的时候会根据order …

3DGS与NeRF的区别

0 论文链接 nerf&#xff1a;https://arxiv.org/abs/2003.08934 3dgs&#xff1a;https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gaussian_splatting_low.pdf 1 简要 1.1 nerf neural radiance fields神经辐射场 作者提出了一种优化来自一组输入图像的场景…

关于python的复习

Python的基础 自动声明: 在 Python 中&#xff0c;不需要显式声明变量类型&#xff0c;变量的类型是在赋值时根据值自动推断的。 动态类型: Python 是动态类型语言&#xff0c;变量的类型可以在运行时改变。 x 10 # 整数 x "hello" # 现在是字符串 变量…

HBuilderX运行微信小程序,编译的文件在哪,怎么运行

1. 点击HBuilderX顶部的运行-运行到小程序模拟器-微信开发者工具&#xff0c;就会开始编译 2. 编译完成后的文件在根目录找到 unpackage -- dist -- dev -- mp-weixin, 这里面就是编译后的文件&#xff0c;如果未跳转到开发者工具&#xff0c;那可能是没设置启动路径&#xff0…

自然语言处理在客户服务中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 自然语言处理在客户服务中的应用 自然语言处理在客户服务中的应用 自然语言处理在客户服务中的应用 引言 自然语言处理概述 定义…