第十三届蓝桥杯Java、C++、Python组国赛真题——最大公约数(三语言AC)

1.问题描述

给定一个数组, 每次操作可以选择数组中任意两个相邻的元素 x , y x, y x ,y 并将其 中的一个元素替换为 gcd ⁡ ( x , y ) \operatorname{gcd}(x, y)gcd (x ,y ), 其中 gcd ⁡ ( x , y ) \operatorname{gcd}(x, y)gcd (x ,y ) 表示 x x x 和 y y y 的最大公约数。 请问最少需要多少次操作才能让整个数组只含 1 。

2.输入格式

输入的第一行包含一个整数 n n n, 表示数组长度。

第二行包含 n n n 个整数 a 1 , a 2 , ⋯ , a n a_{1}, a_{2}, \cdots, a_{n}a 1 ​,a 2 ​,⋯,a n ​ 相邻两个整数之间用一个空格分隔。

2.输出格式

输出一行包含一个整数, 表示最少操作次数。如果无论怎么操作都无法满 足要求, 输出 − 1 −1 −1 。

3.样例输入

4 6 9

4.样例输出

5.数据范围

1 ≤ n ≤ 100000 , 1 ≤ a i ≤ 1 0 9 1≤n≤100000,1≤a i ≤10^9 1 ≤n ≤100000 ,1 ≤ai ≤1 0 9

6.原题连接

首先先考虑数组中是否存在1 1 1,如果数组中存在1 1 1,那么我们可以直接进行平铺把全部变成1 1 1,假设1 1 1的个数为x x x个,那么最终的答案应该是n − x n-x n −x次。

如果原数组中不存在1 1 1,该如何呢?那么我们应该想方法变出一个1 1 1,然后使用这个1 1 1进行平推将数组全部变成1 1 1。关于g c d gcd g c d,我们首先要明白—— 如果一段子数组的的g c d gcd g c d 为1 1 1,那么原数组的g c d gcd g c d 也一定为1 1 1 。 这也非常容易理解,如果存在一个数组的g c d gcd g c d为1 1 1,那么这个数组无论再加上任何正整数,g c d gcd g c d也永远是1 1 1, 因为1 1 1 和任何数的g c d gcd g c d 都是1 1 1 。

题意要求最少次数,那么在没有1 1 1的情况下,我们需要使用最少的步数获得1 1 1,那么就是我们需要在数组中找到最短的子数组,使得它们的g c d gcd g c d为1。所以我们会涉及道查询区间g c d gcd g c d这个操作,直接暴力肯定不可取,所以我们应该联想到线段树来进行查询。

那么如何寻找最短的子数组满足区间g c d gcd g c d为1 1 1呢?我们可以考虑 二分。对于数组中的每个数我们都可以固定为左端点l l l,然后去二分它的右端点,求出使得区间[ l , r ] [l,r][l ,r ]的g c d gcd g c d为1 1 1的 最小的右端点。既然二分就需要满足二段性,根据上一段的描述,我们可以知道,如果[ l , r ] [l,r][l ,r ]的 g c d gcd g c d 为1 1 1,那么[ l , r + 1 ] . . . [ l , n ] [l,r+1]…[l,n][l ,r +1 ]…[l ,n ]这些区间的g c d gcd g c d也一定为1 1 1,
而[ l , l + 1 ] . . . [ l , r − 1 ] [l,l+1]…[l,r-1][l ,l +1 ]…[l ,r −1 ]这些区间却并不一定符合条件。这样每个数我们都定为左端点去二分它的右端点,所有答案取最小值就能找出g c d gcd g c d位1 1 1的最短区间。

当然我们如何判断无解的情况呢?还是根据上述g c d gcd g c d的理论知识,如果[ 1 , n ] [1,n][1 ,n ]的g c d gcd g c d都不为1 1 1,那么任何子数组的g c d gcd g c d也不可能为1 1 1,此时为无解。

注意:Python语言运行较慢,推荐写成 st 表,不推荐写线段树,线段树常数太大。不过任何语言都推荐写 st 表,代码较短
时间复杂度O ( n l o g 2 n ) O(nlog^2n)O (n l o g 2 n )。

C++

#include
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N=100010;

int n;
int a[N];
struct node
{
    int l, r;
    int g;
}tr[N * 4];

void pushup(int u)
{
    tr[u].g =__gcd(tr[u<<1].g,tr[u<<1|1].g);
}

void build(int u, int l, int r)
{
    if (l == r) tr[u] = {l, r, a[r]};
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

int query(int u, int l, int r)
{
    if (tr[u].l >= l && tr[u].r  r) return tr[u].g;
    int mid = tr[u].l + tr[u].r >> 1;
    if(rmid) return query(u<<1,l,r);
    else if(l>mid) return query(u<<1|1,l,r);
    else return __gcd(query(u<<1,l,r),query(u<<1|1,l,r));
}
void solve()
{
    cin>>n;
    int f=0;
    for(int i=1;in;++i){
        cin>>a[i];
        if(a[i]==1) f++;
    }
    if(f){
        printf("%d\n",n-f);
        return;
    }
    build(1,1,n);
    if(query(1,1,n)!=1){
        puts("-1");
        return;
    }
    int ans=inf;
    for(int i=1;in;++i){
        int l=i+1,r=n+1;
        while(l<r){
            int mid=l+r>>1;
            if(query(1,i,mid)==1) r=mid;
            else l=mid+1;
        }
        if(query(1,i,r)==1) ans=min(ans,r-i);
    }
    printf("%d\n",n-1+ans);
}
int main()
{
    solve();
    return 0;
}

C++ ST表

#include
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
#define pb(s) push_back(s);
#define SZ(s) ((int)s.size());
#define ms(s,x) memset(s, x, sizeof(s))
#define all(s) s.begin(),s.end()
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N = 200010;

int n;
int f[N][21], Log2[N], b[N];
void build() {
    for (int i = 2; i  n; ++i)
        Log2[i] = Log2[i / 2] + 1;
    for (int i = 1; i  n; i++)
        f[i][0] = b[i];
    for (int i = 1; i  20; ++i)
        for (int j = 1; j + (1 << i) - 1  n; ++j)
            f[j][i] = __gcd(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);
}
int query(int L, int R) {
    int s = Log2[R - L + 1];
    return __gcd(f[L][s], f[R - (1 << s) + 1][s]);
}
void solve()
{
    cin >> n;
    int f = 0;
    for (int i = 1; i  n; ++i) {
        cin >> b[i];
        if (b[i] == 1) f++;
    }

    if (f) {
        cout << n - f << '\n';
        return;
    }
    build();

    if (query(1, n) != 1) {
        cout << -1 << '\n';
        return;
    }
    int ans = n;
    for (int i = 1; i  n; ++i) {
        int l = i + 1, r = n + 1;
        while (l < r) {
            int mid = l + r >> 1;
            if (query(i, mid) == 1) r = mid;
            else l = mid + 1;
        }
        if (query( i, r) == 1) ans = min(ans, r - i);
    }
    cout << n - 1 + ans << '\n';
}
int main()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t = 1;
    while (t--)
    {
        solve();
    }
    return 0;
}

Java

import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Scanner;

public class Main {
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    static int N = 100010;
    static Node[] tr = new Node[N * 4];
    static int[] a = new int[N];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int f = 0;
        for (int i = 1; i  n; ++i) {
            a[i] = sc.nextInt();
            if (a[i] == 1) f++;
        }
        if (f != 0) {
            out.println(n - f);
            out.flush();
            return;
        }
        build(1, 1, n);
        if (query(1, 1, n) != 1) {
            out.println(-1);
            out.flush();
            return;
        }
        int ans = 0x3f3f3f3f;
        for (int i = 1; i  n; ++i) {
            int l = i + 1, r = n + 1;
            while (l < r) {
                int mid = l + r >> 1;
                if (query(1, i, mid) == 1) r = mid;
                else l = mid + 1;
            }
            if (query(1, i, r) == 1) ans = Math.min(ans, r - i);
        }
        out.println(n - 1 + ans);
        out.flush();
    }

    static int gcd(int a,int b){
        return b == 0 ? a:gcd(b,a%b);
    }

    static void pushup(int u) {
        tr[u].g = gcd(tr[u << 1].g, tr[u << 1 | 1].g);
    }

    static void build(int u, int l, int r) {
        if (l == r) tr[u] = new Node(l, r, a[r]);
        else {
            tr[u] = new Node(l, r, 0);
            int mid = l + r >> 1;
            build(u << 1, l, mid);
            build(u << 1 | 1, mid + 1, r);
            pushup(u);
        }
    }

    static int query(int u, int l, int r) {
        if (tr[u].l >= l && tr[u].r  r) return tr[u].g;
        int mid = tr[u].l + tr[u].r >> 1;
        if (r  mid) return query(u << 1, l, r);
        else if (l > mid) return query(u << 1 | 1, l, r);
        else return gcd(query(u << 1, l, r), query(u << 1 | 1, l, r));
    }

    static class Node {
        int l, r, g;

        public Node(int l, int r, int g) {
            this.l = l;
            this.r = r;
            this.g = g;
        }
    }
}

Pthon

from math import gcd
import math

def rmq_init(arr):
    arr_len = len(arr)
    exp = int(math.log(arr_len, 2))
    dp = [[0] * (exp + 1) for _ in range(arr_len + 1)]
    for i, a in enumerate(arr):
        dp[i + 1][0] = a
    for j in range(1, exp + 1):
        for start in range(1, arr_len + 1):
            if start + (1 << j) - 1 > arr_len:
                break
            dp[start][j] = gcd(dp[start][j - 1], dp[start + (1 << (j - 1))][j - 1])
    return dp

def rmq_ask(dp, left, right):
    k = int(math.log(right - left + 1, 2))
    return gcd(dp[left][k], dp[right + 1 - (1 << k)][k])

n = int(input())
a = list(map(int, input().split()))

cnt1 = sum(ai == 1 for ai in a)
if cnt1 > 0:
    print(n - cnt1)
else:
    dp = rmq_init(a)
    if rmq_ask(dp, 1, n) != 1:
        print(-1)
    else:
        ans = 10 ** 9
        for i in range(1, n):
            l, r = i, n
            while l < r:
                mid = (l + r) >> 1
                if rmq_ask(dp, i, mid) == 1:
                    r = mid
                else:
                    l = mid + 1
            if rmq_ask(dp, i, r) == 1:
                ans = min(ans, r-i)
        print(ans + n-1)

Original: https://blog.csdn.net/m0_57487901/article/details/127393669
Author: 执 梗
Title: 第十三届蓝桥杯Java、C++、Python组国赛真题——最大公约数(三语言AC)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/668859/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 决策树模型

    决策树 • 决策树是一种树形结构 • • 其中每个内部节点表示一个特征上的判断 • • 每个分支代表一个判断结果的输出 • • 最后每个叶节点代表一种分类结果 例子: • 选择一个…

    人工智能 2023年6月13日
    087
  • Python他不香吗?四、五行代码就能搞定几百份表格的拆分!

    作者: 锋小刀微信搜索【Python与Excel之交】关注我的公众号查看更多内容 &#x5F53;&#x4F60;&#x8981;&#x91CD;&…

    人工智能 2023年7月9日
    066
  • TIME-FREQUENCY ATTENTION FOR MONAURAL SPEECH ENHANCEMENT

    [ arXiv:2111.07518v2] Motivation 现有的模型主要关注于如何有效地建模长时间依赖关系,而忽略了语音在T-F表示中的能量分布特征,而能量分布对于准确预测…

    人工智能 2023年5月25日
    0102
  • 当我和ChatGPT聊Everything as Code

    以下是我和ChatGPT的聊天原文。一开始还有点惊喜,震惊。 越到后面,越感到失望。网络上大肆宣传ChatGPT要代替人类的文章,我怕是专门炒流量赚钱的吧? 我个人觉得,它离代替人…

    人工智能 2023年7月31日
    045
  • 聚类算法——KMeans(K-均值)

    聚类的概念 聚类是一种机器学习技术,它涉及到数据点的分组。给定一组数据点,我们可以使用聚类算法将每个数据点划分为一个特定的组。理论上,同一组中的数据点应该具有相似的属性和/或特征,…

    人工智能 2023年7月19日
    067
  • Python数据分析系列5—DataFrame数据操作

    1、索引对象index pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个I…

    人工智能 2023年7月16日
    060
  • 回归模型的损失度量方法

    欢迎关注笔者的微信公众号 之前的分类模型写完后同学问我有没有回归的模型评价方法,现在,它来了 刚开始,我直接搜索回归模型的评价方法有哪些,但是突然想起来之前学习线性回归模型的时候有…

    人工智能 2023年6月18日
    099
  • 解决No module named numpy问题

    目录 前沿 解决 解决方法1: 方法2:(强行安装更新更高的版本) 前沿 最近开始学习python了,由于要简单处理一下图片,奈何能C++力太差,openCV上手有点难,想学习一下…

    人工智能 2023年7月6日
    094
  • Filterin

    Filterin问题的介绍 在信号处理中,Filtering(滤波)是一种常见的技术,用于改变信号的频率响应或去除噪声,从而从输入信号中获得所需的信息。滤波器可以应用于多种领域,例…

    人工智能 2024年1月2日
    044
  • Python攻防-APK批量自动反编译与数据分析

    文章目录 前言 Pull APK * 1.1 根据包名列表 1.2 根据手机路径 逆向APK * 2.1 自动化反编译 2.2 数据快速检索 数据分析 * 3.1 txt文本的比较…

    人工智能 2023年6月11日
    0110
  • 2021 年 10 大数据科学 Python 库

    Python是当今使用最广泛的编程语言。在解决数据科学任务和挑战方面,Python 不断的给用户带来惊喜。大多数数据科学家每天都在利用Python 编程的力量。Python是一种易…

    人工智能 2023年5月26日
    097
  • 愿所有人都不被癌症折磨

    啊哦~你想找的内容离你而去了哦 内容不存在,可能为如下原因导致: ① 内容还在审核中 ② 内容以前存在,但是由于不符合新 的规定而被删除 ③ 内容地址错误 ④ 作者删除了内容。 可…

    人工智能 2023年7月17日
    071
  • 异常检测FastFlow论文详解

    FastFlow 论文链接 https://arxiv.org/pdf/2111.07677v2.pdf Figure 1 : FastFlow的一个例子。 FastFlow将输入…

    人工智能 2023年5月26日
    088
  • Nebula Graph 如何快速导入OwnThink知识图谱数据

    随着社交、电商、金融、零售、物联网等行业的快速发展,现实社会织起了了一张庞大而复杂的关系网,亟需一种支持海量复杂数据关系运算的数据库即图数据库。本系列文章是学习知识图谱以及图数据库…

    人工智能 2023年6月1日
    088
  • 【学习记录】用pytorch自己写数据生成器

    &#x5B66;&#x4E60;&#x8FC7;&#x7A0B;&#x4E2D;&#x7684;&#x8BB0;&#…

    人工智能 2023年7月23日
    050
  • python-matplotlib给图像添加文本标签与注释

    python-matplotlib给图像添加文本标签与注释 文章目录 1.添加文本标签 plt.text() 2. 添加注释 plt.annotate() ʚʕ̯•͡˔•̯᷅ʔɞʚ…

    人工智能 2023年7月4日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球