蓝桥杯第十四讲--数论【例题】

简介: 蓝桥杯第十四讲--数论【例题】

前言

蓝桥杯官网:蓝桥杯大赛——全国大学生TMT行业赛事

✨本博客讲解 蓝桥杯C/C++ 备赛所涉及算法知识,此博客为第十四讲:数论【例题】

本篇博客所包含习题有:

👊等差数列

👊X的因子链

👊五指山


数论【习题】见博客:蓝桥杯第十四讲–数论【习题】


博客内容以题代讲,通过讲解题目的做法来帮助读者快速理解算法内容,需要注意:学习算法不能光过脑,更要实践,请读者务必自己敲写一遍本博客相关代码!!!


等差数列

来源: 第十届蓝桥杯省赛C++B/C组,第十届蓝桥杯省赛JAVAC组

题目要求

题目描述:

数学老师给小明出了一道等差数列求和的题目。

但是粗心的小明忘记了一部分的数列,只记得其中 N 个整数。

现在给出这 N 个整数,小明想知道包含这 N  个整数的最短的等差数列有几项?

输入格式:

image.png

输出格式:

输出一个整数表示答案。

数据范围:

image.png

输入样例:

5
2 6 4 10 20

输出样例:

10

样例解释:

包含 2 、 6 、 4 、 10 、 20 的最短的等差数列是 2 、 4 、 6 、 8 、 10 、 12 、 14 、 16 、 18 、 20。

思路分析

image.png

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N];
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    sort(a, a + n);
    int d = 0;
    for (int i = 1; i < n; i ++ ) d = gcd(d, a[i] - a[0]);
    if (!d) printf("%d\n", n);
    else printf("%d\n", (a[n - 1] - a[0]) / d + 1);
    return 0;
}

X的因子链

题目要求

题目描述:

输入正整数 X ,求 X 的大于 1  的因子组成的满足任意前一项都能整除后一项的严格递增序列的最大长度,以及满足最大长度的序列的个数。

输入格式:

输入包含多组数据,每组数据占一行,包含一个正整数表示 X

输出格式:

对于每组数据,输出序列的最大长度以及满足最大长度的序列的个数。

每个结果占一行。

数据范围:

1X220

输入样例:

2
3
4
10
100

输出样例:

1 1
1 1
2 1
2 2
4 6

思路分析

本题用到了 线性筛法筛质因数,这里不进行赘述,代码如下,详细原理可以参考博客:数学知识:质数

void get_primes(int n)
{
   for (int i = 2; i <= n; i ++ )
   {
       if (!st[i])
       {
           minp[i] = i;
           primes[cnt ++ ] = i;
       }
       for (int j = 0; primes[j] * i <= n; j ++ )
       {
           int t = primes[j] * i;
           st[t] = true;
           minp[t] = primes[j];
           if (i % primes[j] == 0) break;
       }
   }
}

算术基本定理: 所有的正整数都可以唯一的分成若干个质因子乘积的形式,即:

image.png

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = (1 << 20) + 10;
int primes[N], cnt;
int minp[N];
bool st[N];
void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            minp[i] = i;
            primes[cnt ++ ] = i;
        }
        for (int j = 0; primes[j] * i <= n; j ++ )
        {
            int t = primes[j] * i;
            st[t] = true;
            minp[t] = primes[j];
            if (i % primes[j] == 0) break;
        }
    }
}
int main()
{
    get_primes(N - 1);
    int fact[30], sum[N];
    int x;
    while (scanf("%d", &x) != -1)
    {
        int k = 0, tot = 0;
        while (x > 1)
        {
            int p = minp[x];
            fact[k] = p, sum[k] = 0;
            while (x % p == 0)
            {
                x /= p;
                sum[k] ++ ;
                tot ++ ;
            }
            k ++ ;
        }
        LL res = 1;
        for (int i = 1; i <= tot; i ++ ) res *= i;
        for (int i = 0; i < k; i ++ )
            for (int j = 1; j <= sum[i]; j ++ )
                res /= j;
        printf("%d %lld\n", tot, res);
    }
    return 0;
}

五指山

题目要求

题目描述:

大圣在佛祖的手掌中。

我们假设佛祖的手掌是一个圆圈,圆圈的长为 n,逆时针记为:0 , 1 , 2 , … , n − 1 ,而大圣每次飞的距离为 d 。

现在大圣所在的位置记为 x,而大圣想去的地方在 y 。

要你告诉大圣至少要飞多少次才能到达目的地。

注意: 孙悟空的筋斗云只沿着逆时针方向翻。

输入格式:

有多组测试数据。

第一行是一个正整数 T ,表示测试数据的组数;

每组测试数据包括一行,四个非负整数,分别为如来手掌圆圈的长度 n ,筋斗所能飞的距离 d ,大圣的初始位置 x 和大圣想去的地方 y。

输出格式:

对于每组测试数据,输出一行,给出大圣最少要翻多少个筋斗云才能到达目的地。

如果无论翻多少个筋斗云也不能到达,输出Impossible。

数据范围:

image.png

输入样例:

2
3 2 0 2
3 2 0 1

输出样例:

1
2

思路分析

本题用到了 扩展欧几里得算法,具体原理可见博客:数学知识:扩展欧几里得算法

由题目可以抽象出数学模型如下:

image.png

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL exgcd(LL a, LL b, LL &x, LL &y)
{
    if (!b)
    {
        x = 1, y = 0;
        return a;
    }
    LL d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
int main()
{
    int T;
    scanf("%d", &T);
    while (T -- )
    {
        LL n, d, x, y, a, b;
        scanf("%lld%lld%lld%lld", &n, &d, &x, &y);
        int gcd = exgcd(n, d, a, b);
        if ((y - x) % gcd) puts("Impossible");
        else
        {
            b *= (y - x) / gcd;
            n /= gcd;
            printf("%lld\n", (b % n + n) % n);
        }
    }
    return 0;
}







目录
相关文章
|
3天前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
|
9月前
|
算法
[算法刷题题解笔记] 洛谷 P1011 [NOIP1998 提高组] 车站 [数学|斐波那契|推导]
[算法刷题题解笔记] 洛谷 P1011 [NOIP1998 提高组] 车站 [数学|斐波那契|推导]
|
6月前
|
Python
牛客刷题之数学基础-约数
牛客刷题之数学基础-约数
24 0
|
10月前
《蓝桥杯每日一题》递推·AcWing 3777. 砖块
《蓝桥杯每日一题》递推·AcWing 3777. 砖块
50 0
|
10月前
|
机器学习/深度学习
《蓝桥杯每日一题》背包dp·AcWing3382. 整数拆分
《蓝桥杯每日一题》背包dp·AcWing3382. 整数拆分
47 0
|
C++
【寒假每日一题】AcWing 4728. 乘方
目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
107 0
(数论)蓝桥杯AcWing 1205. 买不到的数目
(数论)蓝桥杯AcWing 1205. 买不到的数目
34 0
|
算法 C语言 C++
蓝桥杯第十四讲--数论【习题】
蓝桥杯第十四讲--数论【习题】
125 0
蓝桥杯第十四讲--数论【习题】
|
算法 定位技术 C++
蓝桥杯第十二讲--图论【例题】(一)
蓝桥杯第十二讲--图论【例题】
163 0
蓝桥杯第十二讲--图论【例题】(一)
蓝桥杯第十二讲--图论【例题】(二)
蓝桥杯第十二讲--图论【例题】
94 0
蓝桥杯第十二讲--图论【例题】(二)