试题 H: 等差数列 时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分 【问题描述】 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 N 个整数。 现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有 几项? 【输入格式】 输入的第一行包含一个整数 N。 第二行包含 N 个整数 A1, A2, · · · , AN。(注意 A1 ∼ AN 并不一定是按等差数 列中的顺序给出) 【输出格式】 输出一个整数表示答案。 【样例输入】 5 2 6 4 10 20 【样例输出】 10 【样例说明】 包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。 试题 H: 等差数列
程序思路:
1.求等差数列的第一项a1:已知项的最小值就是a1(求最小值)
2.求等差数列的最后一项an:已知项的最大值就是an(求最大值)
3.求公差d:求出相邻两项的最大公约数,最小的一个最大公约数就是公差d
如:
已知项 | 2 | 4 | 6 | 10 | 20 | ||||
最大公约数 | 2 | 2 | 2 | 10 |
因此数列的d为2,a1为2,an为20
4.已知等差数列的a1,an,d即可求出此等差数列
int f(int x,int y)//辗转相除法求最大公约数
{
int z;
if(x>y)//判断x,y的大小,始终保持x是较小值,y是较大值
{
x=x+y;
y=x-y;
x=x-y;
}
z=y%x;
while(z)
{
y=x;
x=z;
z=y%x;
}
return x;
}
#include"stdio.h"
int main()
{
//n为题目中的已知项数N
//X用于输入每一项,y为x的前一项,存储前一项目的是求相邻两数的最大公约数
//a1为输入中的最小项,an为输入中的最大项
//d 为相邻项的最大公约数中最小的一个公约数
int n,x,y,a1,an,d,i;
scanf("%d",&n);
scanf("%d",&x); //先输入一个x的值,将输入的第一项的值作为a1,an,d的初值
a1=an=d=x;//因为d的值小于或等于数列中的任意一项
for(i=2;i<=n;i++)//因为已经输入了一项,所以循环从第二项开始
{
y=x;//先把前一项的值给y再输入下一项给x,因为要求相邻两项的最大公约数
scanf("%d",&x);
if(a1>x)//找所有项中的最小值
a1=x;
if(an<x)//找最大值
an=x;
int gys=f(x,y);//f(int,int)为自定义函数,用于求两个数的最大公约数
if(d>gys)
d=gys;
}
//已求得a1,an,d;可以求出此数列的最小项数s了
int s=0;
while(a1<=an)
{
s++;
a1=a1+d;
}
printf("%d",s);
return 0;
}
运行结果:
题目示例
![](https://i-blog.csdnimg.cn/blog_migrate/4dad13b174358602334e67a706887121.png)
扩展测试
![](https://i-blog.csdnimg.cn/blog_migrate/20551a538b42422561011e8a706447f7.png)
暴力测试一百万的数字
![](https://i-blog.csdnimg.cn/blog_migrate/846a94a722c18be028fa9e99854e46c4.png)