蓝桥杯:等差数列缺少项,求等差数列最少多少项

题目描述

数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 N 个整数。现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有几项?

输入描述

第一行输入一个整数n

第二行输入等差数量a0,a1,a2,···,a(n-1){需要注意等差数列不一定是按大小排列}

输出描述

输出一个整数。

示例

输入

5

2 6 4 10 20

输出

10

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

 解题思路

先将题目给出的等差数列排序,公差mid一定会小于等于相邻两项之和,对每相邻两项相减,求出最小的差值,设为mid,此时假设公差为mid。

1.对每相邻两项求差再对mid取余数,如果余数都为零那么mid就是最大的公差

2.如果不是公差不是mid,对mid自减,然后重复1过程,即可求出最大公差mid

3.因为sort排序为由小到大排序,所以不用考虑公差为负数的情况

最后,公差越大,项数越小,故(a(n-1)-a(0))/mid+1就是最小项。

因为等差数列的性质,它每相邻两项差恒为mid,那么它间隔m项的差为m*mid,即:对间隔m项的两项求差,差再对mid取余数,余数为0,所以本题可以使用取余的方法判断等差数列公差。

代码


#include<iostream>
#include<algorithm>

using namespace std;

//等差数列缺少项求等差数列最少多少项
int panduan(long* a, int n,int j)
{//判断j是否是公差
	int i,m=1;
	for (i = 0; i < n - 2; i++)
	{
		if ((a[i + 1] - a[i]) % j)
			m = 0;//if函数里的表达式即为余数
	}
	return m;//m为1,j为公差,m为0,j不为公差
}
int main()
{
	int n, mid = 100000, sum,i;
	scanf("%d", &n);
	long a[10000];
	for (i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	sort(a, a + n);//对等差数列排序
	for (i = 0; i < n-2; i++)
	{
		if (a[i + 1] - a[i] < mid)
			mid = a[i + 1] - a[i];
	}
	if (mid == 0)
		sum = n;
	for ( mid; mid!=0 ;mid--)
	{
		if (panduan(a, n, mid))
		{
			sum = (a[n - 1] - a[0]) / mid + 1;
			break;
		}
	}
	cout<< "最少项数为" << sum << endl;
	cout<< "最大公差为" << mid << endl;
	return 0;
}

结果

1、公差为0(通过差直接得出公差)

10
1 1 1 1 1 1 1 1 1 1
最少项数为10
最大公差为0

2、公差为1(通过差直接得出公差)

10
-2 6 0 -1 3 1 5 4 2 7
最少项数为10
最大公差为1

3、不能通过差直接得出公差

10
3 12 30 36 45 54 63 72 81 90
最少项数为30
最大公差为3

上述最小相邻差为36-30=6,与公差3不同。 

5
1 6 9 16 21
最少项数为21
最大公差为1

与上一个相似。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值