等差数列 —— 第十届蓝桥杯省赛C++B/C组

等差数列

题目

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

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

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

输入格式

输入的第一行包含一个整数 N。

第二行包含 N 个整数 A1,A2,···,AN。(注意 A1∼AN 并不一定是按等差数
列中的顺序给出)

输出格式

输出一个整数表示答案。

数据范围

2≤N≤100000,
0≤Ai≤10^9

输入样例:
5
2 6 4 10 20
输出样例:
10
样例解释

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

思路分析:

在这里插入图片描述

代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 1e9;
const int N = 1e5 + 5;
//返回最大公约数
int gcd(int a, int b){
    if(b == 0)return a;
    return gcd(b, a % b);
}
int n, a[N];
int main()
{
    cin>>n;
    for(int i = 1; i <= n; i ++)cin>>a[i];

    sort(a + 1, a + n + 1);

    int d = 0;  //最大能够取到的公差
    for(int i = 2; i <= n; i ++)d = gcd(d, a[i] - a[i - 1]);
    
    if(d == 0)cout<<n<<'\n';
    else cout<< (a[n] - a[1]) / d + 1 <<'\n';
    
    return 0;
}
疑问解答:

问: 为什么d取n个数两两差距最大公约数时,此时等差数列的项数(长度)最小?

答: 因为对于该等差数列我们的首和尾是确定的,分别取n个数中最小值和最大值,否则必然导致等差数列的长度变长或构成的等差数列不合法。那么要该等差数列的长度最小,根据求项数公式,我们就应该让d取得最大值。对于d的取值要满足小于等于这些数两两之间差的最小值,并且d能够整除这些数两两之间差距(d | a[i] - a[i-1]),这样才能保证将两两差距平均分割。则同时满则上述两个要求的就是n个数两两差距的最大公约数。

问: gcd?
答:可以看下这篇文章gcd

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值