2005NOIP普及组真题 4. 循环

线上OJ:

【05NOIP普及组】循环

核心思想:高精度
1、本题用到了标准的高精度乘法模板

void init(int a[]) //传入一个数组
{
    string s; 
    cin >> s;  //读入字符串s 
    a[0] = s.length();   //用a[0]计算字符串s的位数 
    for(i = 1; i <= a[0]; i++)  a[i] = s[a[0]-i] - '0';   //将数串s转换为数组a,并倒序存储 
}
for (i = 1; i <= lena; i++)
{
    x = 0;                                     //用于存放进位
    for (j = 1; j <= lenb; j++)                //对乘数的每一位进行处理
    {
        c[i+j-1] = a[i] * b[j] + x + c[i+j-1]; //当前乘积+上次乘积进位+原数
        x = c[i+j-1] / 10;
        c[i+j-1] %= 10;
    }
    c[i+lenb] = x;                           //进位
}
lenc = lena + lenb;
while (c[lenc] == 0 && lenc > 1)  lenc--;    //删除前导0

2、本题要求的是末 k 位的循环节长度。需要从最低位开始判断
假设一个数的末尾四位数字为 1234,要求 1234 的循环节。
1、先判断最后一位 4 的循环节,假设找到是x,即 ( 1234 ) x (1234)^x (1234)x 的个位保持 4 不变。
2、再找倒数第二位 3 的循环节。为了保证每次循环最后一位都保持 4 不变,故每一轮要以 ( 1234 ) x (1234)^x (1234)x 为基准进行累乘。假设找到是 y,则说明 ( ( 1234 ) x ) y ((1234)^x)^y ((1234)x)y的末两位保持 34 不变。
3、再找倒数第三位 2 的循环节。为了保证每次循环末两位保持 34 不变,故每一轮要以 ( ( 1234 ) x ) y ((1234)^x)^y ((1234)x)y 为基准进行累乘。假设找到是 z,则说明 ( ( ( 1234 ) x ) y ) z (((1234)^x)^y)^z (((1234)x)y)z 的末三位保持 234 不变。
4、再找倒数第四位 1 的循环节。为了保证每次循环末三位保持 234 不变,故每一轮要以 ( ( ( 1234 ) x ) y ) z (((1234)^x)^y)^z (((1234)x)y)z 为基准进行累乘。假设找到是 r,则说明 ( ( ( ( 1234 ) x ) y ) z ) r ((((1234)^x)^y)^z)^r ((((1234)x)y)z)r 的末四位保持 1234 不变。
故 1234 的循环节为 x ∗ y ∗ z ∗ r x*y*z*r xyzr
3、我们将上述的 ( 1234 ) x (1234)^x (1234)x , ( ( 1234 ) x ) y ((1234)^x)^y ((1234)x)y , ( ( ( 1234 ) x ) y ) z (((1234)^x)^y)^z (((1234)x)y)z 称为每一轮的累乘单位
下表描述了基本判断过程:

在这里插入图片描述

题解代码:
#include <bits/stdc++.h>
using namespace std;

const int N = 1005;  // 10^100的数字长度有1000位

int k; //结果取末k位

void Multiply(int a[], int b[], int r[]) //a * b = r 高精乘高精 结果只取末k位
{
    for(int i = 1; i <= a[0]; ++i)
    {
        int x = 0;  // 存放进位
        for(int j = 1; j <= b[0]; ++j)  // 对乘数的每一位进行处理
        {
            r[i+j-1] = a[i]*b[j] + x + r[i+j-1]; // 当前乘积 + 上次乘积进位 + 原数
            x = r[i+j-1] / 10;  // 如果r[i+j-1]超过10,则产生进位
            r[i+j-1] %= 10;     // 仅保留个位
        }
        r[i+b[0]] += x; // 存储最后一次产生的进位
    }

    int len = a[0] + b[0];   // 初始化计算结果的位数(举例,3位数*1位数的结果最多是4位数)
    while(r[len] == 0 && len > 1)  len--;  // 去除前导0

    r[0] = min(len, k);  // 存储计算结果的长度至 r[0]。如果计算结果超过了k位,只取k位
}

// c = c*a ,用于计算累乘乘积。
// 为高精乘高精。在调用Multiply(c, a, r)时返回的结果只取末k位
void Multiply(int c[], int a[])
{
    int r[N] = {};
    Multiply(c, a, r);  // r = a*c
    memcpy(c, r, sizeof(r)); // r复制回c,结果只考虑 r[0]位
}

// a = a*b,用于计算幂次方的乘积。举例 (n^100)^5=n^500
// 高精乘低精
void Multiply(int l[], int j)
{
    int x = 0, i;
    for(i = 1; i <= l[0]; ++i) // 对每一位进行处理(倒序存储,l[1]为个位)
    {
        l[i] = l[i] * j + x; // 每一位相乘,+低位的进位
        x = l[i] / 10;  // 如果l[i]超过10,则产生进位
        l[i] %= 10;     // 仅保留个位
    }
    while(x > 0) // 存储最后一次产生的进位
    {
        l[i] = x % 10;
        x /= 10;
        i++;
    }
    while(l[i] == 0 && i > 1)   i--;  // 去除前导0
    l[0] = i;   // 保存计算结果的长度至 l[0]
}

int main()
{
    int n[N] = {}, a[N] = {}, b[N] = {}, c[N] = {}, l[N] = {1,1}; // n:存储原数;a:累乘单位n^t; b:存储n×n^t,n×n^2t ; c:存储每一轮的累乘结果,如 n^2t;l:循环长度 初值为1
    string s;
    cin >> s >> k;  // 读入字符串s和末尾k

    n[0] = s.length(); // 用n[0]存储数字的长度
    for(int i = 1; i <= n[0]; i++)  n[i] = s[ n[0] - i ] - '0'; // 将数串s转换为数组a,并倒序存储

    memcpy(a, n, sizeof(n)); // 初始化累乘单位
    for(int i = 1; i <= k; ++i) // 从个位开始,逐次计算每一位对应的循环周期。由于 n 是倒序存储,所以n[1]是个位,n[2]是十位,n[3]是百位...
    {
        bool isFound = false;   // 第i位的循环长度是否找到

        c[0] = c[1] = 1; // 存储累乘乘积,初始化为1,c[0]存储c的位数。举例,累乘单位n^t,则c分别为1,n^t,(n^t)^2,(n^t)^3...
        for(int j = 1; j <= 10; ++j)  // 如果累乘单位n^t经过10轮还没有出现重复,则说明不会重复了(因为0-9只有十个数字)。
        {
            Multiply(c, a); // 高精乘高精,计算累乘乘积
            memset(b, 0, sizeof(b));
            Multiply(c, n, b);//高精乘高精 b = c * n
            if(b[i] == n[i])  //如果倒数第i位又变回为原来的倒数第i位
            {
                Multiply(l, j);//高精乘低精 找到第i位的循环长度为j
                isFound = true;
                break;
            }
        }
        if(isFound == false)
        {//如果没找到,则不存在循环长度
            cout << -1;
            return 0;
        }
        memcpy(a, c, sizeof(c));
    }
    for(int i = l[0]; i >= 1; i--)  cout << l[i]; // 逆序输出循环长度
        
    return 0;
}

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

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

相关文章

颠覆与重塑|AI助力汽车开发,汽车智能势不可挡

汽车行业深受人工智能的影响&#xff0c;人工智能正在为我们创造全新的出行方式。随着智能化的加速普及&#xff0c;越来越多的消费者开始关注汽车的智能化。智能化的水平已经成为众多消费者购车的参考因素&#xff0c;也成了车企竞争的主赛道&#xff0c;汽车行业也已经成为人…

高校科研信息管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;反馈管理&#xff0c;操作日志管理&#xff0c;科研项目管理&#xff0c;通知管理 科研人员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;反馈管理&#xff…

[SQL-SERVER:数据库安全及维护]:MSSM工具对用户进行用户授权和角色授权操作

文章目录 直接为用户授权&#xff08;20分&#xff09;1. 创建登录TLogin&#xff0c;自行指定登录密码服务器层面选择 安全性 > 点击 登录名 > 点击右键 > 点击 新建登录名 > 选择sqlserver验证 > 关闭强制登录更改密码异常解决&#xff1a;sqlserver 配置管理…

【最新鸿蒙应用开发】——什么是应用开发模型?Stage模型

在应用程序开发时通常需要使用应用模型来提供必备的组件和运行机制&#xff0c;有了应用模型&#xff0c;开发者可以基于一套统一的模型进行应用开发&#xff0c;使应用开发更简单、高效。接下来谈谈鸿蒙应用开发当中的两种模型&#xff1a; Stage模型&#xff1a; HarmonyOS …

过滤器、监听器、拦截器的区别

过滤器、监听器、拦截器的区别 过滤器&#xff08;filter&#xff09;、监听器&#xff08;Listener&#xff09;是JavaWeb的三大组件。而拦截器&#xff08;Interceptor&#xff09;是Spring框架中的。 我们主要是要分清除过滤器和拦截器的区别&#xff1a; 实现原理&#…

晶体(二):差分晶振

一、定义 差分晶振是一种有源晶体振荡器&#xff0c;输出差分信号&#xff08;由两个相位相反、幅度相等的信号组成&#xff09;&#xff0c;从而消除了共模噪声&#xff0c;具有抗干扰能力强、对参考电平完整性要求较弱、抑制串扰、EMI 能力强、功耗小、速率高、不受温度和电压…

【Ubuntu常用命令】终端个人常用命令总结

【Ubuntu常用命令】终端常用命令总结 查看硬盘挂载情况查看内存占用情况移动或重命名文件和目录复制文件或目录conda安装本地文件 查看硬盘挂载情况 mount 命令会列出当前系统上所有已挂载的文件系统。它会显示挂载点、文件系统类型、挂载选项等信息 mount df 命令用于显示文…

MySQL学习——影响选项文件处理的命令行选项和程序选项修改器

大多数支持选项文件的MySQL程序都处理以下选项。因为这些选项会影响选项文件的处理&#xff0c;所以必须在命令行上给出&#xff0c;而不是在选项文件中给出。为了正常工作&#xff0c;这些选项中的每一个都必须先于其他选项给出&#xff0c;但以下情况除外&#xff1a; -prin…

AK F.*ing leetcode 流浪计划之费马小定理与组合数取模

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 费马小定理与证明 参考 https://zhuanlan.zhihu.com/p/594859227 费马小定理&#xff1a;如果p是一个质数&#xff0c;而正整数a不是p的倍数&#xff0c;那么a(p-1)≡…

继承的基本语法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在编写类时&#xff0c;并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间存在一定的继承关系时&#xff0c;就可以通过继承来达到代…

AI早班车6.3

1.蚂蚁技术日&#xff1a;支付宝三大「AI 管家」亮相。 2.百度赵世奇&#xff1a;百度搜索&#xff0b;文心智能体平台&#xff0c;助力智能体人人可用。 3.腾讯&#xff1a;发布大模型App腾讯元宝。 4.AFAC2024金融智能创新大赛启动&#xff0c;让高质量金融服务人人可用 …

Docker笔记-解决非交互式运行python时print不输出的问题

换句话来说就是在docker中如何不会python的print 只需要在启动时&#xff0c;不让python缓冲其输出。 关键命令如下&#xff1a;PYTHONUNBUFFERED1 如下&#xff1a; docker run -e PYTHONUNBUFFERED1 <your_image> 下面解释下-e "-e"选项的全称是"…

lux和ffmpeg进行下载各大主流自媒体平台视频

1、lux下载&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1WjGbouL3KFTU6LeqZmACpA?pwdagpp 提取码&#xff1a;agpp 2、ffmpeg下载&#xff0c;跟lux放在同一个目录&#xff1b; 3、为lux、ffmpeg设置环境变量&#xff1b; 4、WINR&#xff0c;打开运行&#xff0…

Love-Yi情侣网站3.0存在SQL注入漏洞

目录 1. 前言 2. 网站简介 3. 寻找特征点 3.1 第一次尝试 3.2 第二次尝试 4.资产搜索 5.漏洞复现 5.1 寻找漏洞点 5.2 进行进一步测试 5.2.1 手动测试 1.寻找字段 2.寻找回显位 3.查询当前用户 5.2.2 sqlmap去跑 6.总结 1. 前言 朋友说自己建了一个情侣网站,看到…

chat4-Server端保存聊天消息到mysql

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程&#xff0c;此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…

基于django | 创建app,并启动django

1、删除系统默认的目录路径&#xff1a;BASE_DIR / templetes 2、在终端输入命令&#xff1a; python manage.py startapp app01 # 这里的app01是我创建app的名称 3、如果没有创建成功&#xff0c;手动点击 Creat App , 4、在 setting.py 中找到 INSTALLED_APPS ,添加 ap…

✅count(1)、count(*) 与 count(列名) 的区别

简单来说&#xff1a; COUNT(1) 和 COUNT(*) 表示的是直接查询符合条件的数据库表的行数。而 COUNT(列名) 表示的是查询符合条件的列的值不为 NULL 的行数。 除了查询得到结果集有区别之外&#xff0c;在性能方面 COUNT() 约等于 COUNT(1)&#xff0c;但是 **COUNT() 是 SQL9…

Qt——升级系列(Level Two):Hello Qt 程序实现、项目文件解析、

Hello Qt 程序实现 使用“按钮”实现 纯代码方式实现&#xff1a; // Widget构造函数的实现 Widget::Widget(QWidget *parent): QWidget(parent) // 使用父类构造函数初始化QWidget&#xff0c;传入父窗口指针, ui(new Ui::Widget) // 创建Ui::Widget类的实例&#xff0c;并…

基于GTX 8B10B编码的自定义PHY接收模块(高速收发器十三)

点击进入高速收发器系列文章导航界面 前文完成了发送模块的设计&#xff0c;本文接着完成接收模块的设计&#xff0c;接收模块相对发送模块会更加麻烦。 1、设计思路 前文在讲解官方示例工程时&#xff0c;提到GTX IP的接收部分没有做字对齐&#xff0c;需要用户自己编写字对齐…

微服务:Rabbitmq的基本的消息队列的入门简单使用(消息队列中间件)

先介绍最简单的使用方式&#xff0c;后面还会更新其他使用方法。 简单案例 目录结构 引入依赖&#xff1a; <!--AMQP依赖&#xff0c;包含RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…